aboutsummaryrefslogtreecommitdiffstats
path: root/includes
diff options
context:
space:
mode:
authornobody <nobody@localhost>2004-06-27 00:05:32 +0000
committernobody <nobody@localhost>2004-06-27 00:05:32 +0000
commit0c1d741ff4792d486258b390cf50cf3f9e229511 (patch)
tree55961c46b433ade0739763bee2ba3c4843d13751 /includes
parentd5c8171a3157337557bc54ecb730d7dd35778ca3 (diff)
parent1aaed5fd7c7f4d7ea7abbfc7915bab5954d60a30 (diff)
downloadmediawikicore-1.3.0beta4a.tar.gz
mediawikicore-1.3.0beta4a.zip
This commit was manufactured by cvs2svn to create tag1.3.0beta4a
'REL1_3_0beta4a'.
Diffstat (limited to 'includes')
-rw-r--r--includes/Article.php798
-rw-r--r--includes/Block.php42
-rw-r--r--includes/BlockCache.php12
-rw-r--r--includes/CacheManager.php30
-rw-r--r--includes/Database.php83
-rw-r--r--includes/DatabaseFunctions.php260
-rw-r--r--includes/DatabasePostgreSQL.php549
-rwxr-xr-xincludes/DateFormatter.php52
-rw-r--r--includes/DefaultSettings.php137
-rw-r--r--includes/DifferenceEngine.php44
-rw-r--r--includes/EditPage.php81
-rw-r--r--includes/Feed.php28
-rw-r--r--includes/GlobalFunctions.php326
-rw-r--r--includes/HistoryBlob.php64
-rw-r--r--includes/Image.php21
-rw-r--r--includes/ImagePage.php6
-rw-r--r--includes/LinkCache.php51
-rw-r--r--includes/LoadBalancer.php87
-rw-r--r--includes/MagicWord.php2
-rw-r--r--includes/Math.php4
-rwxr-xr-xincludes/MessageCache.php2
-rw-r--r--includes/ObjectCache.php56
-rw-r--r--includes/OutputPage.php75
-rw-r--r--includes/PageHistory.php32
-rw-r--r--includes/Parser.php1603
-rw-r--r--includes/ParserCache.php89
-rwxr-xr-xincludes/Profiling.php2
-rw-r--r--includes/QueryPage.php2
-rw-r--r--includes/RawPage.php56
-rw-r--r--includes/RecentChange.php80
-rw-r--r--includes/SearchEngine.php11
-rw-r--r--includes/SearchUpdate.php8
-rw-r--r--includes/Setup.php144
-rw-r--r--includes/SiteConfiguration.php65
-rw-r--r--includes/SiteStatsUpdate.php6
-rw-r--r--includes/Skin.php1231
-rw-r--r--includes/SkinCologneBlue.php11
-rw-r--r--includes/SkinNostalgia.php6
-rw-r--r--includes/SkinPHPTal.php291
-rw-r--r--includes/SkinStandard.php4
-rw-r--r--includes/SpecialAllpages.php4
-rw-r--r--includes/SpecialAncientpages.php4
-rw-r--r--includes/SpecialAsksql.php6
-rw-r--r--includes/SpecialCategories.php75
-rw-r--r--includes/SpecialContributions.php42
-rw-r--r--includes/SpecialDeadendpages.php30
-rw-r--r--includes/SpecialListadmins.php37
-rw-r--r--includes/SpecialListusers.php62
-rw-r--r--includes/SpecialLonelypages.php40
-rw-r--r--includes/SpecialMakesysop.php4
-rw-r--r--includes/SpecialPage.php15
-rw-r--r--includes/SpecialPreferences.php27
-rw-r--r--includes/SpecialRandompage.php6
-rw-r--r--includes/SpecialRecentchanges.php4
-rw-r--r--includes/SpecialShortpages.php7
-rw-r--r--includes/SpecialStatistics.php7
-rw-r--r--includes/SpecialUndelete.php18
-rw-r--r--includes/SpecialUnusedimages.php2
-rw-r--r--includes/SpecialUpload.php44
-rw-r--r--includes/SpecialUserlogin.php60
-rw-r--r--includes/SpecialWatchlist.php18
-rw-r--r--includes/SpecialWhatlinkshere.php2
-rw-r--r--includes/Title.php211
-rw-r--r--includes/Tokenizer.php141
-rw-r--r--includes/User.php269
-rw-r--r--includes/UserTalkUpdate.php1
-rw-r--r--includes/ViewCountUpdate.php9
-rw-r--r--includes/WatchedItem.php18
-rw-r--r--includes/memcached-client.php10
69 files changed, 4749 insertions, 2875 deletions
diff --git a/includes/Article.php b/includes/Article.php
index 6ccdb7bb2a40..6dea6747dca4 100644
--- a/includes/Article.php
+++ b/includes/Article.php
@@ -1,11 +1,13 @@
<?php
+# $Id$
+#
# Class representing a Wikipedia article and history.
# See design.doc for an overview.
# Note: edit user interface and cache support functions have been
# moved to separate EditPage and CacheManager classes.
-require_once( "CacheManager.php" );
+require_once( 'CacheManager.php' );
class Article {
/* private */ var $mContent, $mContentLoaded;
@@ -25,39 +27,169 @@ class Article {
$this->mContentLoaded = false;
$this->mCurID = $this->mUser = $this->mCounter = -1; # Not loaded
$this->mRedirectedFrom = $this->mUserText =
- $this->mTimestamp = $this->mComment = $this->mFileCache = "";
+ $this->mTimestamp = $this->mComment = $this->mFileCache = '';
$this->mCountAdjustment = 0;
- $this->mTouched = "19700101000000";
+ $this->mTouched = '19700101000000';
}
- /* static */ function getRevisionText( $row, $prefix = "old_" ) {
- # Deal with optional compression of archived pages.
- # This can be done periodically via maintenance/compressOld.php, and
- # as pages are saved if $wgCompressRevisions is set.
- $text = $prefix . "text";
- $flags = $prefix . "flags";
- if( isset( $row->$flags ) && (false !== strpos( $row->$flags, "gzip" ) ) ) {
- return gzinflate( $row->$text );
+ # Get revision text associated with an old or archive row
+ # $row is usually an object from wfFetchRow(), both the flags and the text field must be included
+ /* static */ function getRevisionText( $row, $prefix = 'old_' ) {
+ # Get data
+ $textField = $prefix . 'text';
+ $flagsField = $prefix . 'flags';
+
+ if ( isset( $row->$flagsField ) ) {
+ $flags = explode( ",", $row->$flagsField );
+ } else {
+ $flags = array();
+ }
+
+ if ( isset( $row->$textField ) ) {
+ $text = $row->$textField;
+ } else {
+ return false;
}
- if( isset( $row->$text ) ) {
- return $row->$text;
+
+ if ( in_array( 'link', $flags ) ) {
+ # Handle link type
+ $text = Article::followLink( $text );
+ } elseif ( in_array( 'gzip', $flags ) ) {
+ # Deal with optional compression of archived pages.
+ # This can be done periodically via maintenance/compressOld.php, and
+ # as pages are saved if $wgCompressRevisions is set.
+ return gzinflate( $text );
}
- return false;
+ return $text;
}
/* static */ function compressRevisionText( &$text ) {
global $wgCompressRevisions;
if( !$wgCompressRevisions ) {
- return "";
+ return '';
}
- if( !function_exists( "gzdeflate" ) ) {
+ if( !function_exists( 'gzdeflate' ) ) {
wfDebug( "Article::compressRevisionText() -- no zlib support, not compressing\n" );
- return "";
+ return '';
}
$text = gzdeflate( $text );
- return "gzip";
+ return 'gzip';
}
+ # Returns the text associated with a "link" type old table row
+ /* static */ function followLink( $link ) {
+ # Split the link into fields and values
+ $lines = explode( '\n', $link );
+ $hash = '';
+ $locations = array();
+ foreach ( $lines as $line ) {
+ # Comments
+ if ( $line{0} == '#' ) {
+ continue;
+ }
+ # Field/value pairs
+ if ( preg_match( '/^(.*?)\s*:\s*(.*)$/', $line, $matches ) ) {
+ $field = strtolower($matches[1]);
+ $value = $matches[2];
+ if ( $field == 'hash' ) {
+ $hash = $value;
+ } elseif ( $field == 'location' ) {
+ $locations[] = $value;
+ }
+ }
+ }
+
+ if ( $hash === '' ) {
+ return false;
+ }
+
+ # Look in each specified location for the text
+ $text = false;
+ foreach ( $locations as $location ) {
+ $text = Article::fetchFromLocation( $location, $hash );
+ if ( $text !== false ) {
+ break;
+ }
+ }
+
+ return $text;
+ }
+
+ /* static */ function fetchFromLocation( $location, $hash ) {
+ global $wgLoadBalancer;
+ $fname = 'fetchFromLocation';
+ wfProfileIn( $fname );
+
+ $p = strpos( $location, ':' );
+ if ( $p === false ) {
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ $type = substr( $location, 0, $p );
+ $text = false;
+ switch ( $type ) {
+ case 'mysql':
+ # MySQL locations are specified by mysql://<machineID>/<dbname>/<tblname>/<index>
+ # Machine ID 0 is the current connection
+ if ( preg_match( '/^mysql:\/\/(\d+)\/([A-Za-z_]+)\/([A-Za-z_]+)\/([A-Za-z_]+)$/',
+ $location, $matches ) ) {
+ $machineID = $matches[1];
+ $dbName = $matches[2];
+ $tblName = $matches[3];
+ $index = $matches[4];
+ if ( $machineID == 0 ) {
+ # Current connection
+ $db =& wfGetDB();
+ } else {
+ # Alternate connection
+ $db =& $wgLoadBalancer->getConnection( $machineID );
+
+ if ( array_key_exists( $machineId, $wgKnownMysqlServers ) ) {
+ # Try to open, return false on failure
+ $params = $wgKnownDBServers[$machineId];
+ $db = Database::newFromParams( $params['server'], $params['user'], $params['password'],
+ $dbName, 1, false, true, true );
+ }
+ }
+ if ( $db->isOpen() ) {
+ $index = wfStrencode( $index );
+ $res = $db->query( "SELECT blob_data FROM $dbName.$tblName WHERE blob_index='$index'", $fname );
+ $row = $db->fetchObject( $res );
+ $text = $row->text_data;
+ }
+ }
+ break;
+ case 'file':
+ # File locations are of the form file://<filename>, relative to the current directory
+ if ( preg_match( '/^file:\/\/(.*)$', $location, $matches ) )
+ $filename = strstr( $location, 'file://' );
+ $text = @file_get_contents( $matches[1] );
+ }
+ if ( $text !== false ) {
+ # Got text, now we need to interpret it
+ # The first line contains information about how to do this
+ $p = strpos( $text, '\n' );
+ $type = substr( $text, 0, $p );
+ $text = substr( $text, $p + 1 );
+ switch ( $type ) {
+ case 'plain':
+ break;
+ case 'gzip':
+ $text = gzinflate( $text );
+ break;
+ case 'object':
+ $object = unserialize( $text );
+ $text = $object->getItem( $hash );
+ break;
+ default:
+ $text = false;
+ }
+ }
+ wfProfileOut( $fname );
+ return $text;
+ }
+
# Note that getContent/loadContent may follow redirects if
# not told otherwise, and so may cause a change to mTitle.
@@ -70,34 +202,34 @@ class Article {
$action = $wgRequest->getText( 'action', 'view' );
$section = $wgRequest->getText( 'section' );
- $fname = "Article::getContent";
+ $fname = 'Article::getContent';
wfProfileIn( $fname );
if ( 0 == $this->getID() ) {
- if ( "edit" == $action ) {
+ if ( 'edit' == $action ) {
wfProfileOut( $fname );
- return ""; # was "newarticletext", now moved above the box)
+ return ''; # was "newarticletext", now moved above the box)
}
wfProfileOut( $fname );
- return wfMsg( "noarticletext" );
+ return wfMsg( 'noarticletext' );
} else {
$this->loadContent( $noredir );
if(
# check if we're displaying a [[User talk:x.x.x.x]] anonymous talk page
( $this->mTitle->getNamespace() == Namespace::getTalk( Namespace::getUser()) ) &&
- preg_match("/^\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3}$/",$this->mTitle->getText()) &&
- $action=="view"
+ preg_match('/^\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3}$/',$this->mTitle->getText()) &&
+ $action=='view'
)
{
wfProfileOut( $fname );
- return $this->mContent . "\n" .wfMsg("anontalkpagetext"); }
+ return $this->mContent . "\n" .wfMsg('anontalkpagetext'); }
else {
- if($action=="edit") {
- if($section!="") {
- if($section=="new") {
+ if($action=='edit') {
+ if($section!='') {
+ if($section=='new') {
wfProfileOut( $fname );
- return "";
+ return '';
}
# strip NOWIKI etc. to avoid confusion (true-parameter causes HTML
@@ -132,18 +264,18 @@ class Article {
# split it up by section
$secs =
preg_split(
- "/(^=+.*?=+|^<h[1-6].*?" . ">.*?<\/h[1-6].*?" . ">)/mi",
+ '/(^=+.*?=+|^<h[1-6].*?' . '>.*?<\/h[1-6].*?' . '>)/mi',
$striptext, -1,
PREG_SPLIT_DELIM_CAPTURE);
if($section==0) {
$rv=$secs[0];
} else {
$headline=$secs[$section*2-1];
- preg_match( "/^(=+).*?=+|^<h([1-6]).*?>.*?<\/h[1-6].*?>/mi",$headline,$matches);
+ preg_match( '/^(=+).*?=+|^<h([1-6]).*?' . '>.*?<\/h[1-6].*?' . '>/mi',$headline,$matches);
$hlevel=$matches[1];
# translate wiki heading into level
- if(strpos($hlevel,"=")!==false) {
+ if(strpos($hlevel,'=')!==false) {
$hlevel=strlen($hlevel);
}
@@ -154,9 +286,9 @@ class Article {
while(!empty($secs[$count*2-1]) && !$break) {
$subheadline=$secs[$count*2-1];
- preg_match( "/^(=+).*?=+|^<h([1-6]).*?>.*?<\/h[1-6].*?>/mi",$subheadline,$matches);
+ preg_match( '/^(=+).*?=+|^<h([1-6]).*?' . '>.*?<\/h[1-6].*?' . '>/mi',$subheadline,$matches);
$subhlevel=$matches[1];
- if(strpos($subhlevel,"=")!==false) {
+ if(strpos($subhlevel,'=')!==false) {
$subhlevel=strlen($subhlevel);
}
if($subhlevel > $hlevel) {
@@ -171,6 +303,7 @@ class Article {
}
# reinsert stripped tags
$rv=$parser->unstrip($rv,$striparray);
+ $rv=$parser->unstripNoWiki($rv,$striparray);
$rv=trim($rv);
return $rv;
@@ -180,14 +313,14 @@ class Article {
# Load the revision (including cur_text) into this object
function loadContent( $noredir = false )
{
- global $wgOut, $wgMwRedir, $wgRequest;
+ global $wgOut, $wgMwRedir, $wgRequest, $wgIsPg;
# Query variables :P
$oldid = $wgRequest->getVal( 'oldid' );
$redirect = $wgRequest->getVal( 'redirect' );
if ( $this->mContentLoaded ) return;
- $fname = "Article::loadContent";
+ $fname = 'Article::loadContent';
# Pre-fill content with error message so that if something
# fails we'll have something telling us what we intended.
@@ -198,17 +331,17 @@ class Article {
$t .= ",oldid={$oldid}";
}
if ( isset( $redirect ) ) {
- $redirect = ($redirect == "no") ? "no" : "yes";
+ $redirect = ($redirect == 'no') ? 'no' : 'yes';
$t .= ",redirect={$redirect}";
}
- $this->mContent = wfMsg( "missingarticle", $t );
+ $this->mContent = wfMsg( 'missingarticle', $t );
if ( ! $oldid ) { # Retrieve current version
$id = $this->getID();
if ( 0 == $id ) return;
- $sql = "SELECT " .
- "cur_text,cur_timestamp,cur_user,cur_counter,cur_restrictions,cur_touched " .
+ $sql = 'SELECT ' .
+ 'cur_text,cur_timestamp,cur_user,cur_user_text,cur_comment,cur_counter,cur_restrictions,cur_touched ' .
"FROM cur WHERE cur_id={$id}";
wfDebug( "$sql\n" );
$res = wfQuery( $sql, DB_READ, $fname );
@@ -219,9 +352,9 @@ class Article {
$s = wfFetchObject( $res );
# If we got a redirect, follow it (unless we've been told
# not to by either the function parameter or the query
- if ( ( "no" != $redirect ) && ( false == $noredir ) &&
+ if ( ( 'no' != $redirect ) && ( false == $noredir ) &&
( $wgMwRedir->matchStart( $s->cur_text ) ) ) {
- if ( preg_match( "/\\[\\[([^\\]\\|]+)[\\]\\|]/",
+ if ( preg_match( '/\\[\\[([^\\]\\|]+)[\\]\\|]/',
$s->cur_text, $m ) ) {
$rt = Title::newFromText( $m[1] );
if( $rt ) {
@@ -229,7 +362,7 @@ class Article {
# Fill the HTTP response "Location" header and ignore
# the rest of the page we're on.
- if ( $rt->getInterwiki() != "" ) {
+ if ( $rt->getInterwiki() != '' ) {
$wgOut->redirect( $rt->getFullURL() ) ;
return;
}
@@ -239,7 +372,7 @@ class Article {
}
$rid = $rt->getArticleID();
if ( 0 != $rid ) {
- $sql = "SELECT cur_text,cur_timestamp,cur_user," .
+ $sql = 'SELECT cur_text,cur_timestamp,cur_user,cur_user_text,cur_comment,' .
"cur_counter,cur_restrictions,cur_touched FROM cur WHERE cur_id={$rid}";
$res = wfQuery( $sql, DB_READ, $fname );
@@ -255,15 +388,19 @@ class Article {
$this->mContent = $s->cur_text;
$this->mUser = $s->cur_user;
+ $this->mUserText = $s->cur_user_text;
+ $this->mComment = $s->cur_comment;
$this->mCounter = $s->cur_counter;
$this->mTimestamp = $s->cur_timestamp;
$this->mTouched = $s->cur_touched;
- $this->mTitle->mRestrictions = explode( ",", trim( $s->cur_restrictions ) );
+ $this->mTitle->mRestrictions = explode( ',', trim( $s->cur_restrictions ) );
$this->mTitle->mRestrictionsLoaded = true;
wfFreeResult( $res );
} else { # oldid set, retrieve historical version
- $sql = "SELECT old_namespace,old_title,old_text,old_timestamp,old_user,old_flags FROM old " .
- "WHERE old_id={$oldid}";
+ $oldtable=$wgIsPg?'"old"':'old';
+ $sql = "SELECT old_namespace,old_title,old_text,old_timestamp,".
+ "old_user,old_user_text,old_comment,old_flags FROM old ".
+ "WHERE old_id={$oldid}";
$res = wfQuery( $sql, DB_READ, $fname );
if ( 0 == wfNumRows( $res ) ) {
return;
@@ -278,6 +415,8 @@ class Article {
}
$this->mContent = Article::getRevisionText( $s );
$this->mUser = $s->old_user;
+ $this->mUserText = $s->old_user_text;
+ $this->mComment = $s->old_comment;
$this->mCounter = 0;
$this->mTimestamp = $s->old_timestamp;
wfFreeResult( $res );
@@ -289,14 +428,14 @@ class Article {
# Gets the article text without using so many damn globals
# Returns false on error
function getContentWithoutUsingSoManyDamnGlobals( $oldid = 0, $noredir = false ) {
- global $wgMwRedir;
+ global $wgMwRedir, $wgIsPg;
if ( $this->mContentLoaded ) {
return $this->mContent;
}
$this->mContent = false;
- $fname = "Article::loadContent";
+ $fname = 'Article::loadContent';
if ( ! $oldid ) { # Retrieve current version
$id = $this->getID();
@@ -304,8 +443,8 @@ class Article {
return false;
}
- $sql = "SELECT " .
- "cur_text,cur_timestamp,cur_user,cur_counter,cur_restrictions,cur_touched " .
+ $sql = 'SELECT ' .
+ 'cur_text,cur_timestamp,cur_user,cur_counter,cur_restrictions,cur_touched ' .
"FROM cur WHERE cur_id={$id}";
$res = wfQuery( $sql, DB_READ, $fname );
if ( 0 == wfNumRows( $res ) ) {
@@ -316,13 +455,13 @@ class Article {
# If we got a redirect, follow it (unless we've been told
# not to by either the function parameter or the query
if ( !$noredir && $wgMwRedir->matchStart( $s->cur_text ) ) {
- if ( preg_match( "/\\[\\[([^\\]\\|]+)[\\]\\|]/",
+ if ( preg_match( '/\\[\\[([^\\]\\|]+)[\\]\\|]/',
$s->cur_text, $m ) ) {
$rt = Title::newFromText( $m[1] );
- if( $rt && $rt->getInterwiki() == "" && $rt->getNamespace() != Namespace::getSpecial() ) {
+ if( $rt && $rt->getInterwiki() == '' && $rt->getNamespace() != Namespace::getSpecial() ) {
$rid = $rt->getArticleID();
if ( 0 != $rid ) {
- $sql = "SELECT cur_text,cur_timestamp,cur_user," .
+ $sql = 'SELECT cur_text,cur_timestamp,cur_user,' .
"cur_counter,cur_restrictions,cur_touched FROM cur WHERE cur_id={$rid}";
$res = wfQuery( $sql, DB_READ, $fname );
@@ -345,7 +484,8 @@ class Article {
$this->mTitle->mRestrictionsLoaded = true;
wfFreeResult( $res );
} else { # oldid set, retrieve historical version
- $sql = "SELECT old_text,old_timestamp,old_user,old_flags FROM old " .
+ $oldtable=$wgIsPg?'"old"':'old';
+ $sql = "SELECT old_text,old_timestamp,old_user,old_flags FROM $oldtable " .
"WHERE old_id={$oldid}";
$res = wfQuery( $sql, DB_READ, $fname );
if ( 0 == wfNumRows( $res ) ) {
@@ -375,7 +515,7 @@ class Article {
{
if ( -1 == $this->mCounter ) {
$id = $this->getID();
- $this->mCounter = wfGetSQL( "cur", "cur_counter", "cur_id={$id}" );
+ $this->mCounter = wfGetSQL( 'cur', 'cur_counter', "cur_id={$id}" );
}
return $this->mCounter;
}
@@ -389,7 +529,7 @@ class Article {
if ( 0 != $this->mTitle->getNamespace() ) { return 0; }
if ( $wgMwRedir->matchStart( $text ) ) { return 0; }
- $token = ($wgUseCommaCount ? "," : "[[" );
+ $token = ($wgUseCommaCount ? ',' : '[[' );
if ( false === strstr( $text, $token ) ) { return 0; }
return 1;
}
@@ -402,10 +542,10 @@ class Article {
global $wgOut;
if ( -1 != $this->mUser ) return;
- $sql = "SELECT cur_user,cur_user_text,cur_timestamp," .
- "cur_comment,cur_minor_edit FROM cur WHERE " .
- "cur_id=" . $this->getID();
- $res = wfQuery( $sql, DB_READ, "Article::loadLastEdit" );
+ $sql = 'SELECT cur_user,cur_user_text,cur_timestamp,' .
+ 'cur_comment,cur_minor_edit FROM cur WHERE ' .
+ 'cur_id=' . $this->getID();
+ $res = wfQuery( $sql, DB_READ, 'Article::loadLastEdit' );
if ( wfNumRows( $res ) > 0 ) {
$s = wfFetchObject( $res );
@@ -449,7 +589,7 @@ class Article {
function getContributors($limit = 0, $offset = 0)
{
- $fname = "Article::getContributors";
+ $fname = 'Article::getContributors';
# XXX: this is expensive; cache this info somewhere.
@@ -457,19 +597,19 @@ class Article {
$contribs = array();
- $sql = "SELECT old.old_user, old.old_user_text, " .
- " user.user_real_name, MAX(old.old_timestamp) as timestamp" .
- " FROM old, user " .
- " WHERE old.old_user = user.user_id " .
- " AND old.old_namespace = " . $title->getNamespace() .
- " AND old.old_title = \"" . $title->getDBkey() . "\"" .
- " AND old.old_user != 0 " .
- " AND old.old_user != " . $this->getUser() .
- " GROUP BY old.old_user " .
- " ORDER BY timestamp DESC ";
+ $sql = 'SELECT old.old_user, old.old_user_text, ' .
+ ' user.user_real_name, MAX(old.old_timestamp) as timestamp' .
+ ' FROM old, user ' .
+ ' WHERE old.old_user = user.user_id ' .
+ ' AND old.old_namespace = ' . $title->getNamespace() .
+ ' AND old.old_title = "' . $title->getDBkey() . '"' .
+ ' AND old.old_user != 0 ' .
+ ' AND old.old_user != ' . $this->getUser() .
+ ' GROUP BY old.old_user ' .
+ ' ORDER BY timestamp DESC ';
if ($limit > 0) {
- $sql .= " LIMIT $limit";
+ $sql .= ' LIMIT '.$limit;
}
$res = wfQuery($sql, DB_READ, $fname);
@@ -481,11 +621,11 @@ class Article {
# Count anonymous users
- $res = wfQuery("SELECT COUNT(*) AS cnt " .
- " FROM old " .
- " WHERE old_namespace = " . $title->getNamespace() .
+ $res = wfQuery('SELECT COUNT(*) AS cnt ' .
+ ' FROM old ' .
+ ' WHERE old_namespace = ' . $title->getNamespace() .
" AND old_title = '" . $title->getDBkey() . "'" .
- " AND old_user = 0 ", DB_READ, $fname);
+ ' AND old_user = 0 ', DB_READ, $fname);
while ( $line = wfFetchObject( $res ) ) {
$contribs[0] = array($line->cnt, 'Anonymous');
@@ -502,7 +642,7 @@ class Article {
global $wgUser, $wgOut, $wgLang, $wgRequest;
global $wgLinkCache, $IP, $wgEnableParserCache;
- $fname = "Article::view";
+ $fname = 'Article::view';
wfProfileIn( $fname );
# Get variables from query string :P
@@ -510,7 +650,7 @@ class Article {
$diff = $wgRequest->getVal( 'diff' );
$wgOut->setArticleFlag( true );
- $wgOut->setRobotpolicy( "index,follow" );
+ $wgOut->setRobotpolicy( 'index,follow' );
# If we got diff and oldid in the query, we want to see a
# diff page instead of the article.
@@ -533,48 +673,67 @@ class Article {
return;
}
}
-
- $text = $this->getContent( false ); # May change mTitle by following a redirect
- # Another whitelist check in case oldid or redirects are altering the title
- if ( !$this->mTitle->userCanRead() ) {
- $wgOut->loginToUse();
- $wgOut->output();
- exit;
+ # Should the parser cache be used?
+ if ( $wgEnableParserCache && intval($wgUser->getOption( 'stubthreshold' )) == 0 && empty( $oldid ) ) {
+ $pcache = true;
+ } else {
+ $pcache = false;
}
- $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
+ $outputDone = false;
+ if ( $pcache ) {
+ if ( $wgOut->tryParserCache( $this, $wgUser ) ) {
+ $outputDone = true;
+ }
+ }
- # We're looking at an old revision
+ if ( !$outputDone ) {
+ $text = $this->getContent( false ); # May change mTitle by following a redirect
+
+ # Another whitelist check in case oldid or redirects are altering the title
+ if ( !$this->mTitle->userCanRead() ) {
+ $wgOut->loginToUse();
+ $wgOut->output();
+ exit;
+ }
+
- if ( !empty( $oldid ) ) {
- $this->setOldSubtitle();
- $wgOut->setRobotpolicy( "noindex,follow" );
- }
- if ( "" != $this->mRedirectedFrom ) {
- $sk = $wgUser->getSkin();
- $redir = $sk->makeKnownLink( $this->mRedirectedFrom, "",
- "redirect=no" );
- $s = wfMsg( "redirectedfrom", $redir );
- $wgOut->setSubtitle( $s );
- }
+ # We're looking at an old revision
- $wgLinkCache->preFill( $this->mTitle );
+ if ( !empty( $oldid ) ) {
+ $this->setOldSubtitle();
+ $wgOut->setRobotpolicy( 'noindex,follow' );
+ }
+ if ( '' != $this->mRedirectedFrom ) {
+ $sk = $wgUser->getSkin();
+ $redir = $sk->makeKnownLink( $this->mRedirectedFrom, '',
+ 'redirect=no' );
+ $s = wfMsg( 'redirectedfrom', $redir );
+ $wgOut->setSubtitle( $s );
+
+ # Can't cache redirects
+ $pcache = false;
+ }
- # wrap user css and user js in pre and don't parse
- # XXX: use $this->mTitle->usCssJsSubpage() when php is fixed/ a workaround is found
- if (
- $this->mTitle->getNamespace() == Namespace::getUser() &&
- preg_match("/\\/[\\w]+\\.(css|js)$/", $this->mTitle->getDBkey())
- ) {
- $wgOut->addWikiText( wfMsg('usercssjs'));
- $wgOut->addHTML( '<pre>'.htmlspecialchars($this->mContent)."\n</pre>" );
- } else if( $wgEnableParserCache && intval($wgUser->getOption( "stubthreshold" )) == 0 ){
- $wgOut->addWikiText( $text, true, $this );
- } else {
- $wgOut->addWikiText( $text );
+ $wgLinkCache->preFill( $this->mTitle );
+
+ # wrap user css and user js in pre and don't parse
+ # XXX: use $this->mTitle->usCssJsSubpage() when php is fixed/ a workaround is found
+ if (
+ $this->mTitle->getNamespace() == Namespace::getUser() &&
+ preg_match('/\\/[\\w]+\\.(css|js)$/', $this->mTitle->getDBkey())
+ ) {
+ $wgOut->addWikiText( wfMsg('clearyourcache'));
+ $wgOut->addHTML( '<pre>'.htmlspecialchars($this->mContent)."\n</pre>" );
+ } else if ( $pcache ) {
+ $wgOut->addWikiText( $text, true, $this );
+ } else {
+ $wgOut->addWikiText( $text );
+ }
}
-
+ $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
+
# Add link titles as META keywords
$wgOut->addMetaTags() ;
@@ -590,9 +749,9 @@ class Article {
/* private */ function insertNewArticle( $text, $summary, $isminor, $watchthis )
{
global $wgOut, $wgUser, $wgLinkCache, $wgMwRedir;
- global $wgUseSquid, $wgDeferredUpdateList, $wgInternalServer;
+ global $wgUseSquid, $wgDeferredUpdateList, $wgInternalServer, $wgIsPg, $wgIsMySQL;
- $fname = "Article::insertNewArticle";
+ $fname = 'Article::insertNewArticle';
$this->mCountAdjustment = $this->isCountable( $text );
@@ -605,12 +764,23 @@ class Article {
$now = wfTimestampNow();
$won = wfInvertTimestamp( $now );
wfSeedRandom();
- $rand = number_format( mt_rand() / mt_getrandmax(), 12, ".", "" );
+ $rand = number_format( mt_rand() / mt_getrandmax(), 12, '.', '' );
+
+ if ($wgIsPg) {
+ $cur_id_column="cur_id,";
+ $cur_id=wfGetSQL(""," nextval('cur_cur_id_seq')");
+ $cur_id_value="{$cur_id},";
+ } else {
+ $cur_id_column="";
+ $cur_id="";
+ $cur_id_value="";
+ }
+
$isminor = ( $isminor && $wgUser->getID() ) ? 1 : 0;
- $sql = "INSERT INTO cur (cur_namespace,cur_title,cur_text," .
- "cur_comment,cur_user,cur_timestamp,cur_minor_edit,cur_counter," .
- "cur_restrictions,cur_user_text,cur_is_redirect," .
- "cur_is_new,cur_random,cur_touched,inverse_timestamp) VALUES ({$ns},'" . wfStrencode( $ttl ) . "', '" .
+ $sql = "INSERT INTO cur ({$cur_id_column}cur_namespace,cur_title,cur_text," .
+ 'cur_comment,cur_user,cur_timestamp,cur_minor_edit,cur_counter,' .
+ 'cur_restrictions,cur_user_text,cur_is_redirect,' .
+ "cur_is_new,cur_random,cur_touched,inverse_timestamp) VALUES ({$cur_id_value}{$ns},'" . wfStrencode( $ttl ) . "', '" .
wfStrencode( $text ) . "', '" .
wfStrencode( $summary ) . "', '" .
$wgUser->getID() . "', '{$now}', " .
@@ -618,7 +788,7 @@ class Article {
wfStrencode( $wgUser->getName() ) . "', $redir, 1, $rand, '{$now}', '{$won}')";
$res = wfQuery( $sql, DB_WRITE, $fname );
- $newid = wfInsertId();
+ $newid = $wgIsPg?$cur_id:wfInsertId();
$this->mTitle->resetArticleID( $newid );
Article::onArticleCreate( $this->mTitle );
@@ -640,16 +810,16 @@ class Article {
# standard deferred updates
$this->editUpdates( $text );
- $this->showArticle( $text, wfMsg( "newarticle" ) );
+ $this->showArticle( $text, wfMsg( 'newarticle' ) );
}
/* Side effects: loads last edit */
- function getTextOfLastEditWithSectionReplacedOrAdded($section, $text, $summary = ""){
+ function getTextOfLastEditWithSectionReplacedOrAdded($section, $text, $summary = ''){
$this->loadLastEdit();
$oldtext = $this->getContent( true );
- if ($section != "") {
- if($section=="new") {
+ if ($section != '') {
+ if($section=='new') {
if($summary) $subject="== {$summary} ==\n\n";
$text=$oldtext."\n\n".$subject.$text;
} else {
@@ -665,7 +835,7 @@ class Article {
# split it up
# Unfortunately we can't simply do a preg_replace because that might
# replace the wrong section, so we have to use the section counter instead
- $secs=preg_split("/(^=+.*?=+|^<h[1-6].*?" . ">.*?<\/h[1-6].*?" . ">)/mi",
+ $secs=preg_split('/(^=+.*?=+|^<h[1-6].*?' . '>.*?<\/h[1-6].*?' . '>)/mi',
$oldtext,-1,PREG_SPLIT_DELIM_CAPTURE);
$secs[$section*2]=$text."\n\n"; // replace with edited
@@ -677,30 +847,30 @@ class Article {
# be erased, as the mother section has been replaced with
# the text of all subsections.
$headline=$secs[$section*2-1];
- preg_match( "/^(=+).*?=+|^<h([1-6]).*?>.*?<\/h[1-6].*?>/mi",$headline,$matches);
+ preg_match( '/^(=+).*?=+|^<h([1-6]).*?' . '>.*?<\/h[1-6].*?' . '>/mi',$headline,$matches);
$hlevel=$matches[1];
# determine headline level for wikimarkup headings
- if(strpos($hlevel,"=")!==false) {
+ if(strpos($hlevel,'=')!==false) {
$hlevel=strlen($hlevel);
}
- $secs[$section*2-1]=""; // erase old headline
+ $secs[$section*2-1]=''; // erase old headline
$count=$section+1;
$break=false;
while(!empty($secs[$count*2-1]) && !$break) {
$subheadline=$secs[$count*2-1];
preg_match(
- "/^(=+).*?=+|^<h([1-6]).*?>.*?<\/h[1-6].*?>/mi",$subheadline,$matches);
+ '/^(=+).*?=+|^<h([1-6]).*?' . '>.*?<\/h[1-6].*?' . '>/mi',$subheadline,$matches);
$subhlevel=$matches[1];
- if(strpos($subhlevel,"=")!==false) {
+ if(strpos($subhlevel,'=')!==false) {
$subhlevel=strlen($subhlevel);
}
if($subhlevel > $hlevel) {
// erase old subsections
- $secs[$count*2-1]="";
- $secs[$count*2]="";
+ $secs[$count*2-1]='';
+ $secs[$count*2]='';
}
if($subhlevel <= $hlevel) {
$break=true;
@@ -710,25 +880,27 @@ class Article {
}
}
- $text=join("",$secs);
+ $text=join('',$secs);
# reinsert the stuff that we stripped out earlier
$text=$parser->unstrip($text,$striparray);
+ $text=$parser->unstripNoWiki($text,$striparray);
}
}
return $text;
}
- function updateArticle( $text, $summary, $minor, $watchthis, $forceBot = false, $sectionanchor = "" )
+ function updateArticle( $text, $summary, $minor, $watchthis, $forceBot = false, $sectionanchor = '' )
{
global $wgOut, $wgUser, $wgLinkCache;
global $wgDBtransactions, $wgMwRedir;
global $wgUseSquid, $wgInternalServer;
- $fname = "Article::updateArticle";
+ global $wgIsPg;
+ $fname = 'Article::updateArticle';
if ( $this->mMinorEdit ) { $me1 = 1; } else { $me1 = 0; }
if ( $minor && $wgUser->getID() ) { $me2 = 1; } else { $me2 = 0; }
- if ( preg_match( "/^((" . $wgMwRedir->getBaseRegex() . ")[^\\n]+)/i", $text, $m ) ) {
+ if ( preg_match( "/^((" . $wgMwRedir->getBaseRegex() . ')[^\\n]+)/i', $text, $m ) ) {
$redir = 1;
$text = $m[1] . "\n"; # Remove all content but redirect
}
@@ -739,7 +911,7 @@ class Article {
# Update article, but only if changed.
if( $wgDBtransactions ) {
- $sql = "BEGIN";
+ $sql = 'BEGIN';
wfQuery( $sql, DB_WRITE );
}
$oldtext = $this->getContent( true );
@@ -768,9 +940,22 @@ class Article {
# This overwrites $oldtext if revision compression is on
$flags = Article::compressRevisionText( $oldtext );
- $sql = "INSERT INTO old (old_namespace,old_title,old_text," .
- "old_comment,old_user,old_user_text,old_timestamp," .
- "old_minor_edit,inverse_timestamp,old_flags) VALUES (" .
+ $oldtable=$wgIsPg?'"old"':'old';
+ if ($wgIsPg) {
+ $oldtable='"old"';
+ $old_id_column='old_id,';
+ $old_id=wfGetSQL(""," nextval('old_old_id_seq')");
+ $old_id_value=$old_id.',';
+ } else {
+ $oldtable='old';
+ $old_id_column='';
+ $old_id_value='';
+ }
+
+ $sql = "INSERT INTO $oldtable ({$old_id_column}old_namespace,old_title,old_text," .
+ 'old_comment,old_user,old_user_text,old_timestamp,' .
+ 'old_minor_edit,inverse_timestamp,old_flags) VALUES (' .
+ $old_id_value.
$this->mTitle->getNamespace() . ", '" .
wfStrencode( $this->mTitle->getDBkey() ) . "', '" .
wfStrencode( $oldtext ) . "', '" .
@@ -780,7 +965,8 @@ class Article {
$this->getTimestamp() . "', " . $me1 . ", '" .
wfInvertTimestamp( $this->getTimestamp() ) . "','$flags')";
$res = wfQuery( $sql, DB_WRITE, $fname );
- $oldid = wfInsertID( $res );
+
+ $oldid = $wgIsPg?$old_id:wfInsertId( $res );
$bot = (int)($wgUser->isBot() || $forceBot);
RecentChange::notifyEdit( $now, $this->mTitle, $me2, $wgUser, $summary,
@@ -789,7 +975,7 @@ class Article {
}
if( $wgDBtransactions ) {
- $sql = "COMMIT";
+ $sql = 'COMMIT';
wfQuery( $sql, DB_WRITE );
}
@@ -824,7 +1010,7 @@ class Article {
$u->doUpdate();
}
- $this->showArticle( $text, wfMsg( "updated" ), $sectionanchor );
+ $this->showArticle( $text, wfMsg( 'updated' ), $sectionanchor );
return true;
}
@@ -847,9 +1033,9 @@ class Article {
$wgOut->addWikiText( $text );
if( $wgMwRedir->matchStart( $text ) )
- $r = "redirect=no";
+ $r = 'redirect=no';
else
- $r = "";
+ $r = '';
$wgOut->redirect( $this->mTitle->getFullURL( $r ).$sectionanchor );
}
@@ -861,7 +1047,7 @@ class Article {
global $wgDeferredUpdateList;
if ( 0 == $wgUser->getID() ) {
- $wgOut->errorpage( "watchnologin", "watchnologintext" );
+ $wgOut->errorpage( 'watchnologin', 'watchnologintext' );
return;
}
if ( wfReadOnly() ) {
@@ -873,16 +1059,16 @@ class Article {
else
$wgUser->removeWatch( $this->mTitle );
- $wgOut->setPagetitle( wfMsg( $add ? "addedwatch" : "removedwatch" ) );
- $wgOut->setRobotpolicy( "noindex,follow" );
+ $wgOut->setPagetitle( wfMsg( $add ? 'addedwatch' : 'removedwatch' ) );
+ $wgOut->setRobotpolicy( 'noindex,follow' );
$sk = $wgUser->getSkin() ;
$link = $this->mTitle->getPrefixedText();
if($add)
- $text = wfMsg( "addedwatchtext", $link );
+ $text = wfMsg( 'addedwatchtext', $link );
else
- $text = wfMsg( "removedwatchtext", $link );
+ $text = wfMsg( 'removedwatchtext', $link );
$wgOut->addWikiText( $text );
$up = new UserUpdate();
@@ -896,7 +1082,7 @@ class Article {
$this->watch( false );
}
- function protect( $limit = "sysop" )
+ function protect( $limit = 'sysop' )
{
global $wgUser, $wgOut, $wgRequest;
@@ -910,7 +1096,7 @@ class Article {
}
$id = $this->mTitle->getArticleID();
if ( 0 == $id ) {
- $wgOut->fatalError( wfMsg( "badarticleerror" ) );
+ $wgOut->fatalError( wfMsg( 'badarticleerror' ) );
return;
}
@@ -921,50 +1107,50 @@ class Article {
$sql = "UPDATE cur SET cur_touched='" . wfTimestampNow() . "'," .
"cur_restrictions='{$limit}' WHERE cur_id={$id}";
- wfQuery( $sql, DB_WRITE, "Article::protect" );
+ wfQuery( $sql, DB_WRITE, 'Article::protect' );
- $log = new LogPage( wfMsg( "protectlogpage" ), wfMsg( "protectlogtext" ) );
+ $log = new LogPage( wfMsg( 'protectlogpage' ), wfMsg( 'protectlogtext' ) );
if ( $limit === "" ) {
- $log->addEntry( wfMsg( "unprotectedarticle", $this->mTitle->getPrefixedText() ), $reason );
+ $log->addEntry( wfMsg( 'unprotectedarticle', $this->mTitle->getPrefixedText() ), $reason );
} else {
- $log->addEntry( wfMsg( "protectedarticle", $this->mTitle->getPrefixedText() ), $reason );
+ $log->addEntry( wfMsg( 'protectedarticle', $this->mTitle->getPrefixedText() ), $reason );
}
$wgOut->redirect( $this->mTitle->getFullURL() );
return;
} else {
- $reason = htmlspecialchars( wfMsg( "protectreason" ) );
- return $this->confirmProtect( "", $reason, $limit );
+ $reason = htmlspecialchars( wfMsg( 'protectreason' ) );
+ return $this->confirmProtect( '', $reason, $limit );
}
}
# Output protection confirmation dialog
- function confirmProtect( $par, $reason, $limit = "sysop" )
+ function confirmProtect( $par, $reason, $limit = 'sysop' )
{
global $wgOut;
wfDebug( "Article::confirmProtect\n" );
$sub = htmlspecialchars( $this->mTitle->getPrefixedText() );
- $wgOut->setRobotpolicy( "noindex,nofollow" );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
- $check = "";
- $protcom = "";
+ $check = '';
+ $protcom = '';
- if ( $limit === "" ) {
- $wgOut->setSubtitle( wfMsg( "unprotectsub", $sub ) );
- $wgOut->addWikiText( wfMsg( "confirmunprotecttext" ) );
- $check = htmlspecialchars( wfMsg( "confirmunprotect" ) );
- $protcom = htmlspecialchars( wfMsg( "unprotectcomment" ) );
- $formaction = $this->mTitle->escapeLocalURL( "action=unprotect" . $par );
+ if ( $limit === '' ) {
+ $wgOut->setSubtitle( wfMsg( 'unprotectsub', $sub ) );
+ $wgOut->addWikiText( wfMsg( 'confirmunprotecttext' ) );
+ $check = htmlspecialchars( wfMsg( 'confirmunprotect' ) );
+ $protcom = htmlspecialchars( wfMsg( 'unprotectcomment' ) );
+ $formaction = $this->mTitle->escapeLocalURL( 'action=unprotect' . $par );
} else {
- $wgOut->setSubtitle( wfMsg( "protectsub", $sub ) );
- $wgOut->addWikiText( wfMsg( "confirmprotecttext" ) );
- $check = htmlspecialchars( wfMsg( "confirmprotect" ) );
- $protcom = htmlspecialchars( wfMsg( "protectcomment" ) );
- $formaction = $this->mTitle->escapeLocalURL( "action=protect" . $par );
+ $wgOut->setSubtitle( wfMsg( 'protectsub', $sub ) );
+ $wgOut->addWikiText( wfMsg( 'confirmprotecttext' ) );
+ $check = htmlspecialchars( wfMsg( 'confirmprotect' ) );
+ $protcom = htmlspecialchars( wfMsg( 'protectcomment' ) );
+ $formaction = $this->mTitle->escapeLocalURL( 'action=protect' . $par );
}
- $confirm = htmlspecialchars( wfMsg( "confirm" ) );
+ $confirm = htmlspecialchars( wfMsg( 'confirm' ) );
$wgOut->addHTML( "
<form id='protectconfirm' method='post' action=\"{$formaction}\">
@@ -1002,14 +1188,14 @@ class Article {
function unprotect()
{
- return $this->protect( "" );
+ return $this->protect( '' );
}
# UI entry point for page deletion
function delete()
{
- global $wgUser, $wgOut, $wgMessageCache, $wgRequest;
- $fname = "Article::delete";
+ global $wgUser, $wgOut, $wgMessageCache, $wgRequest, $wgIsPg;
+ $fname = 'Article::delete';
$confirm = $wgRequest->getBool( 'wpConfirm' ) && $wgRequest->wasPosted();
$reason = $wgRequest->getText( 'wpReason' );
@@ -1026,10 +1212,10 @@ class Article {
}
# Better double-check that it hasn't been deleted yet!
- $wgOut->setPagetitle( wfMsg( "confirmdelete" ) );
- if ( ( "" == trim( $this->mTitle->getText() ) )
+ $wgOut->setPagetitle( wfMsg( 'confirmdelete' ) );
+ if ( ( '' == trim( $this->mTitle->getText() ) )
or ( $this->mTitle->getArticleId() == 0 ) ) {
- $wgOut->fatalError( wfMsg( "cannotdelete" ) );
+ $wgOut->fatalError( wfMsg( 'cannotdelete' ) );
return;
}
@@ -1044,12 +1230,13 @@ class Article {
$ns = $this->mTitle->getNamespace();
$title = $this->mTitle->getDBkey();
$etitle = wfStrencode( $title );
- $sql = "SELECT old_text,old_flags FROM old WHERE old_namespace=$ns and old_title='$etitle' ORDER BY inverse_timestamp LIMIT 1";
+ $oldtable=$wgIsPg?'"old"':'old';
+ $sql = "SELECT old_text,old_flags FROM $oldtable WHERE old_namespace=$ns and old_title='$etitle' ORDER BY inverse_timestamp LIMIT 1";
$res = wfQuery( $sql, DB_READ, $fname );
if( ($old=wfFetchObject($res)) && !$confirm ) {
$skin=$wgUser->getSkin();
- $wgOut->addHTML("<b>".wfMsg("historywarning"));
- $wgOut->addHTML( $skin->historyLink() ."</b>");
+ $wgOut->addHTML('<b>'.wfMsg('historywarning'));
+ $wgOut->addHTML( $skin->historyLink() .'</b>');
}
$sql="SELECT cur_text FROM cur WHERE cur_namespace=$ns and cur_title='$etitle'";
@@ -1074,31 +1261,31 @@ class Article {
# this should not happen, since it is not possible to store an empty, new
# page. Let's insert a standard text in case it does, though
- if($length == 0 && $reason === "") {
- $reason = wfMsg("exblank");
+ if($length == 0 && $reason === '') {
+ $reason = wfMsg('exblank');
}
- if($length < 500 && $reason === "") {
+ if($length < 500 && $reason === '') {
# comment field=255, let's grep the first 150 to have some user
# space left
$text=substr($text,0,150);
# let's strip out newlines and HTML tags
- $text=preg_replace("/\"/","'",$text);
- $text=preg_replace("/\</","&lt;",$text);
- $text=preg_replace("/\>/","&gt;",$text);
- $text=preg_replace("/[\n\r]/","",$text);
+ $text=preg_replace('/\"/',"'",$text);
+ $text=preg_replace('/\</','&lt;',$text);
+ $text=preg_replace('/\>/','&gt;',$text);
+ $text=preg_replace("/[\n\r]/",'',$text);
if(!$blanked) {
- $reason=wfMsg("excontent"). " '".$text;
+ $reason=wfMsg('excontent'). " '".$text;
} else {
- $reason=wfMsg("exbeforeblank") . " '".$text;
+ $reason=wfMsg('exbeforeblank') . " '".$text;
}
- if($length>150) { $reason .= "..."; } # we've only pasted part of the text
+ if($length>150) { $reason .= '...'; } # we've only pasted part of the text
$reason.="'";
}
}
- return $this->confirmDelete( "", $reason );
+ return $this->confirmDelete( '', $reason );
}
# Output deletion confirmation dialog
@@ -1109,15 +1296,15 @@ class Article {
wfDebug( "Article::confirmDelete\n" );
$sub = htmlspecialchars( $this->mTitle->getPrefixedText() );
- $wgOut->setSubtitle( wfMsg( "deletesub", $sub ) );
- $wgOut->setRobotpolicy( "noindex,nofollow" );
- $wgOut->addWikiText( wfMsg( "confirmdeletetext" ) );
+ $wgOut->setSubtitle( wfMsg( 'deletesub', $sub ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->addWikiText( wfMsg( 'confirmdeletetext' ) );
- $formaction = $this->mTitle->escapeLocalURL( "action=delete" . $par );
+ $formaction = $this->mTitle->escapeLocalURL( 'action=delete' . $par );
- $confirm = htmlspecialchars( wfMsg( "confirm" ) );
- $check = htmlspecialchars( wfMsg( "confirmcheck" ) );
- $delcom = htmlspecialchars( wfMsg( "deletecomment" ) );
+ $confirm = htmlspecialchars( wfMsg( 'confirm' ) );
+ $check = htmlspecialchars( wfMsg( 'confirmcheck' ) );
+ $delcom = htmlspecialchars( wfMsg( 'deletecomment' ) );
$wgOut->addHTML( "
<form id='deleteconfirm' method='post' action=\"{$formaction}\">
@@ -1157,26 +1344,26 @@ class Article {
function doDelete( $reason )
{
global $wgOut, $wgUser, $wgLang;
- $fname = "Article::doDelete";
+ $fname = 'Article::doDelete';
wfDebug( "$fname\n" );
if ( $this->doDeleteArticle( $reason ) ) {
$deleted = $this->mTitle->getPrefixedText();
- $wgOut->setPagetitle( wfMsg( "actioncomplete" ) );
- $wgOut->setRobotpolicy( "noindex,nofollow" );
+ $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
$sk = $wgUser->getSkin();
$loglink = $sk->makeKnownLink( $wgLang->getNsText(
Namespace::getWikipedia() ) .
- ":" . wfMsg( "dellogpage" ), wfMsg( "deletionlog" ) );
+ ':' . wfMsg( 'dellogpage' ), wfMsg( 'deletionlog' ) );
$text = wfMsg( "deletedtext", $deleted, $loglink );
- $wgOut->addHTML( "<p>" . $text . "</p>\n" );
+ $wgOut->addHTML( '<p>' . $text . "</p>\n" );
$wgOut->returnToMain( false );
} else {
- $wgOut->fatalError( wfMsg( "cannotdelete" ) );
+ $wgOut->fatalError( wfMsg( 'cannotdelete' ) );
}
}
@@ -1188,14 +1375,14 @@ class Article {
global $wgUser, $wgLang;
global $wgUseSquid, $wgDeferredUpdateList, $wgInternalServer;
- $fname = "Article::doDeleteArticle";
- wfDebug( "$fname\n" );
+ $fname = 'Article::doDeleteArticle';
+ wfDebug( $fname."\n" );
$ns = $this->mTitle->getNamespace();
$t = wfStrencode( $this->mTitle->getDBkey() );
$id = $this->mTitle->getArticleID();
- if ( "" == $t || $id == 0 ) {
+ if ( '' == $t || $id == 0 ) {
return false;
}
@@ -1208,7 +1395,7 @@ class Article {
if ( $wgUseSquid ) {
$urls = array(
$this->mTitle->getInternalURL(),
- $this->mTitle->getInternalURL( "history" )
+ $this->mTitle->getInternalURL( 'history' )
);
foreach ( $linksTo as $linkTo ) {
$urls[] = $linkTo->getInternalURL();
@@ -1223,17 +1410,17 @@ class Article {
Title::touchArray( $linksTo );
# Move article and history to the "archive" table
- $sql = "INSERT INTO archive (ar_namespace,ar_title,ar_text," .
- "ar_comment,ar_user,ar_user_text,ar_timestamp,ar_minor_edit," .
- "ar_flags) SELECT cur_namespace,cur_title,cur_text,cur_comment," .
- "cur_user,cur_user_text,cur_timestamp,cur_minor_edit,0 FROM cur " .
+ $sql = 'INSERT INTO archive (ar_namespace,ar_title,ar_text,' .
+ 'ar_comment,ar_user,ar_user_text,ar_timestamp,ar_minor_edit,' .
+ 'ar_flags) SELECT cur_namespace,cur_title,cur_text,cur_comment,' .
+ 'cur_user,cur_user_text,cur_timestamp,cur_minor_edit,0 FROM cur ' .
"WHERE cur_namespace={$ns} AND cur_title='{$t}'";
wfQuery( $sql, DB_WRITE, $fname );
- $sql = "INSERT INTO archive (ar_namespace,ar_title,ar_text," .
- "ar_comment,ar_user,ar_user_text,ar_timestamp,ar_minor_edit," .
- "ar_flags) SELECT old_namespace,old_title,old_text,old_comment," .
- "old_user,old_user_text,old_timestamp,old_minor_edit,old_flags " .
+ $sql = 'INSERT INTO archive (ar_namespace,ar_title,ar_text,' .
+ 'ar_comment,ar_user,ar_user_text,ar_timestamp,ar_minor_edit,' .
+ 'ar_flags) SELECT old_namespace,old_title,old_text,old_comment,' .
+ 'old_user,old_user_text,old_timestamp,old_minor_edit,old_flags ' .
"FROM old WHERE old_namespace={$ns} AND old_title='{$t}'";
wfQuery( $sql, DB_WRITE, $fname );
@@ -1256,11 +1443,11 @@ class Article {
Article::onArticleDelete( $this->mTitle );
- $sql = "INSERT INTO brokenlinks (bl_from,bl_to) VALUES ";
+ $sql = 'INSERT INTO brokenlinks (bl_from,bl_to) VALUES ';
$first = true;
foreach ( $linksTo as $titleObj ) {
- if ( ! $first ) { $sql .= ","; }
+ if ( ! $first ) { $sql .= ','; }
$first = false;
# Get article ID. Efficient because it was loaded into the cache by getLinksTo().
$linkID = $titleObj->getArticleID();
@@ -1285,9 +1472,9 @@ class Article {
$sql = "DELETE FROM categorylinks WHERE cl_from={$id}";
wfQuery( $sql, DB_WRITE, $fname );
- $log = new LogPage( wfMsg( "dellogpage" ), wfMsg( "dellogpagetext" ) );
+ $log = new LogPage( wfMsg( 'dellogpage' ), wfMsg( 'dellogpagetext' ) );
$art = $this->mTitle->getPrefixedText();
- $log->addEntry( wfMsg( "deletedarticle", $art ), $reason );
+ $log->addEntry( wfMsg( 'deletedarticle', $art ), $reason );
# Clear the cached article id so the interface doesn't act like we exist
$this->mTitle->resetArticleID( 0 );
@@ -1297,7 +1484,7 @@ class Article {
function rollback()
{
- global $wgUser, $wgLang, $wgOut, $wgRequest;
+ global $wgUser, $wgLang, $wgOut, $wgRequest, $wgIsMySQL, $wgIsPg;
if ( ! $wgUser->isSysop() ) {
$wgOut->sysopRequired();
@@ -1316,11 +1503,12 @@ class Article {
$n = $this->mTitle->getNamespace();
# Get the last editor
- $sql = "SELECT cur_id,cur_user,cur_user_text,cur_comment FROM cur WHERE cur_title='{$tt}' AND cur_namespace={$n}";
+ $sql = 'SELECT cur_id,cur_user,cur_user_text,cur_comment ' .
+ "FROM cur WHERE cur_title='{$tt}' AND cur_namespace={$n}";
$res = wfQuery( $sql, DB_READ );
if( ($x = wfNumRows( $res )) != 1 ) {
# Something wrong
- $wgOut->addHTML( wfMsg( "notanarticle" ) );
+ $wgOut->addHTML( wfMsg( 'notanarticle' ) );
return;
}
$s = wfFetchObject( $res );
@@ -1328,48 +1516,51 @@ class Article {
$uid = $s->cur_user;
$pid = $s->cur_id;
- $from = str_replace( '_', ' ', $wgRequest->getVal( "from" ) );
+ $from = str_replace( '_', ' ', $wgRequest->getVal( 'from' ) );
if( $from != $s->cur_user_text ) {
- $wgOut->setPageTitle(wfmsg("rollbackfailed"));
- $wgOut->addWikiText( wfMsg( "alreadyrolled",
+ $wgOut->setPageTitle(wfmsg('rollbackfailed'));
+ $wgOut->addWikiText( wfMsg( 'alreadyrolled',
htmlspecialchars( $this->mTitle->getPrefixedText()),
htmlspecialchars( $from ),
htmlspecialchars( $s->cur_user_text ) ) );
- if($s->cur_comment != "") {
+ if($s->cur_comment != '') {
$wgOut->addHTML(
- wfMsg("editcomment",
+ wfMsg('editcomment',
htmlspecialchars( $s->cur_comment ) ) );
}
return;
}
# Get the last edit not by this guy
- $sql = "SELECT old_text,old_user,old_user_text,old_timestamp,old_flags
- FROM old USE INDEX (name_title_timestamp)
- WHERE old_namespace={$n} AND old_title='{$tt}'
- AND (old_user <> {$uid} OR old_user_text <> '{$ut}')
- ORDER BY inverse_timestamp LIMIT 1";
+
+ $use_index=$wgIsMySQL?"USE INDEX (name_title_timestamp)":"";
+ $oldtable=$wgIsPg?'"old"':'old';
+ $sql = 'SELECT old_text,old_user,old_user_text,old_timestamp,old_flags ' .
+ "FROM $oldtable {$use_index} " .
+ "WHERE old_namespace={$n} AND old_title='{$tt}' " .
+ "AND (old_user <> {$uid} OR old_user_text <> '{$ut}') " .
+ 'ORDER BY inverse_timestamp LIMIT 1';
$res = wfQuery( $sql, DB_READ );
if( wfNumRows( $res ) != 1 ) {
# Something wrong
- $wgOut->setPageTitle(wfMsg("rollbackfailed"));
- $wgOut->addHTML( wfMsg( "cantrollback" ) );
+ $wgOut->setPageTitle(wfMsg('rollbackfailed'));
+ $wgOut->addHTML( wfMsg( 'cantrollback' ) );
return;
}
$s = wfFetchObject( $res );
if ( $bot ) {
# Mark all reverted edits as bot
- $sql = "UPDATE recentchanges SET rc_bot=1 WHERE
- rc_cur_id=$pid AND rc_user=$uid AND rc_timestamp > '{$s->old_timestamp}'";
+ $sql = 'UPDATE recentchanges SET rc_bot=1 WHERE ' .
+ "rc_cur_id=$pid AND rc_user=$uid AND rc_timestamp > '{$s->old_timestamp}'";
wfQuery( $sql, DB_WRITE, $fname );
}
# Save it!
- $newcomment = wfMsg( "revertpage", $s->old_user_text, $from );
- $wgOut->setPagetitle( wfMsg( "actioncomplete" ) );
- $wgOut->setRobotpolicy( "noindex,nofollow" );
- $wgOut->addHTML( "<h2>" . $newcomment . "</h2>\n<hr />\n" );
+ $newcomment = wfMsg( 'revertpage', $s->old_user_text, $from );
+ $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
+ $wgOut->addHTML( '<h2>' . $newcomment . "</h2>\n<hr />\n" );
$this->updateArticle( Article::getRevisionText( $s ), $newcomment, 1, $this->mTitle->userIsWatching(), $bot );
Article::onArticleEdit( $this->mTitle );
$wgOut->returnToMain( false );
@@ -1436,7 +1627,7 @@ class Article {
global $wgLang, $wgOut;
$td = $wgLang->timeanddate( $this->mTimestamp, true );
- $r = wfMsg( "revisionasof", $td );
+ $r = wfMsg( 'revisionasof', $td );
$wgOut->setSubtitle( "({$r})" );
}
@@ -1463,7 +1654,7 @@ class Article {
$called = true;
if($this->isFileCacheable()) {
$touched = $this->mTouched;
- if( $this->mTitle->getPrefixedDBkey() == wfMsg( "mainpage" ) ) {
+ if( $this->mTitle->getPrefixedDBkey() == wfMsg( 'mainpage' ) ) {
# Expire the main page quicker
$expire = wfUnix2Timestamp( time() - 3600 );
$touched = max( $expire, $touched );
@@ -1493,7 +1684,7 @@ class Article {
and ($wgUser->getId() == 0)
and (!$wgUser->getNewtalk())
and ($this->mTitle->getNamespace() != Namespace::getSpecial())
- and ($action == "view")
+ and ($action == 'view')
and (!isset($oldid))
and (!isset($diff))
and (!isset($redirect))
@@ -1501,10 +1692,11 @@ class Article {
and (!$this->mRedirectedFrom);
}
+ # Loads cur_touched and returns a value indicating if it should be used
function checkTouched() {
$id = $this->getID();
- $sql = "SELECT cur_touched,cur_is_redirect FROM cur WHERE cur_id=$id";
- $res = wfQuery( $sql, DB_READ, "Article::checkTouched" );
+ $sql = 'SELECT cur_touched,cur_is_redirect FROM cur WHERE cur_id='.$id;
+ $res = wfQuery( $sql, DB_READ, 'Article::checkTouched' );
if( $s = wfFetchObject( $res ) ) {
$this->mTouched = $s->cur_touched;
return !$s->cur_is_redirect;
@@ -1512,15 +1704,64 @@ class Article {
return false;
}
}
-
+
+ # Edit an article without doing all that other stuff
+ function quickEdit( $text, $comment = '', $minor = 0 ) {
+ global $wgUser, $wgMwRedir, $wgIsPg;
+ $fname = 'Article::quickEdit';
+ wfProfileIn( $fname );
+
+ $ns = $this->mTitle->getNamespace();
+ $dbkey = $this->mTitle->getDBkey();
+ $encDbKey = wfStrencode( $dbkey );
+ $timestamp = wfTimestampNow();
+
+ # Save to history
+ $oldtable=$wgIsPg?'"old"':'old';
+ $sql = "INSERT INTO $oldtable (old_namespace,old_title,old_text,old_comment,old_user,old_user_text,old_timestamp,inverse_timestamp)
+ SELECT cur_namespace,cur_title,cur_text,cur_comment,cur_user,cur_user_text,cur_timestamp,99999999999999-cur_timestamp
+ FROM cur WHERE cur_namespace=$ns AND cur_title='$encDbKey'";
+ wfQuery( $sql, DB_WRITE );
+
+ # Use the affected row count to determine if the article is new
+ $numRows = wfAffectedRows();
+
+ # Make an array of fields to be inserted
+ $fields = array(
+ 'cur_text' => $text,
+ 'cur_timestamp' => $timestamp,
+ 'cur_user' => $wgUser->getID(),
+ 'cur_user_text' => $wgUser->getName(),
+ 'inverse_timestamp' => wfInvertTimestamp( $timestamp ),
+ 'cur_comment' => $comment,
+ 'cur_is_redirect' => $wgMwRedir->matchStart( $text ) ? 1 : 0,
+ 'cur_minor_edit' => intval($minor),
+ 'cur_touched' => $timestamp,
+ );
+
+ if ( $numRows ) {
+ # Update article
+ $fields['cur_is_new'] = 0;
+ wfUpdateArray( 'cur', $fields, array( 'cur_namespace' => $ns, 'cur_title' => $dbkey ), $fname );
+ } else {
+ # Insert new article
+ $fields['cur_is_new'] = 1;
+ $fields['cur_namespace'] = $ns;
+ $fields['cur_title'] = $dbkey;
+ $fields['cur_random'] = $rand = number_format( mt_rand() / mt_getrandmax(), 12, '.', '' );
+ wfInsertArray( 'cur', $fields, $fname );
+ }
+ wfProfileOut( $fname );
+ }
+
/* static */ function incViewCount( $id )
{
$id = intval( $id );
global $wgHitcounterUpdateFreq;
if( $wgHitcounterUpdateFreq <= 1 ){ //
- wfQuery("UPDATE cur SET cur_counter = cur_counter + 1 " .
- "WHERE cur_id = $id", DB_WRITE);
+ wfQuery('UPDATE cur SET cur_counter = cur_counter + 1 ' .
+ 'WHERE cur_id = '.$id, DB_WRITE);
return;
}
@@ -1536,25 +1777,25 @@ class Article {
return;
}
- $res = wfQuery("SELECT COUNT(*) as n FROM hitcounter", DB_WRITE);
+ $res = wfQuery('SELECT COUNT(*) as n FROM hitcounter', DB_WRITE);
$row = wfFetchObject( $res );
$rown = intval( $row->n );
if( $rown >= $wgHitcounterUpdateFreq ){
- wfProfileIn( "Article::incViewCount-collect" );
+ wfProfileIn( 'Article::incViewCount-collect' );
$old_user_abort = ignore_user_abort( true );
- wfQuery("LOCK TABLES hitcounter WRITE", DB_WRITE);
- wfQuery("CREATE TEMPORARY TABLE acchits TYPE=HEAP ".
- "SELECT hc_id,COUNT(*) AS hc_n FROM hitcounter ".
- "GROUP BY hc_id", DB_WRITE);
- wfQuery("DELETE FROM hitcounter", DB_WRITE);
- wfQuery("UNLOCK TABLES", DB_WRITE);
- wfQuery("UPDATE cur,acchits SET cur_counter=cur_counter + hc_n ".
- "WHERE cur_id = hc_id", DB_WRITE);
- wfQuery("DROP TABLE acchits", DB_WRITE);
+ wfQuery('LOCK TABLES hitcounter WRITE', DB_WRITE);
+ wfQuery('CREATE TEMPORARY TABLE acchits TYPE=HEAP '.
+ 'SELECT hc_id,COUNT(*) AS hc_n FROM hitcounter '.
+ 'GROUP BY hc_id', DB_WRITE);
+ wfQuery('DELETE FROM hitcounter', DB_WRITE);
+ wfQuery('UNLOCK TABLES', DB_WRITE);
+ wfQuery('UPDATE cur,acchits SET cur_counter=cur_counter + hc_n '.
+ 'WHERE cur_id = hc_id', DB_WRITE);
+ wfQuery('DROP TABLE acchits', DB_WRITE);
ignore_user_abort( $old_user_abort );
- wfProfileOut( "Article::incViewCount-collect" );
+ wfProfileOut( 'Article::incViewCount-collect' );
}
wfIgnoreSQLErrors( $oldignore );
}
@@ -1567,7 +1808,7 @@ class Article {
# This is called on page move and undelete, as well as edit
/* static */ function onArticleCreate($title_obj){
- global $wgEnablePersistentLC, $wgEnableParserCache, $wgUseSquid, $wgDeferredUpdateList;
+ global $wgUseSquid, $wgDeferredUpdateList;
$titles = $title_obj->getBrokenLinksTo();
@@ -1582,34 +1823,15 @@ class Article {
}
# Clear persistent link cache
- if ( $wgEnablePersistentLC ) {
- LinkCache::linksccClearBrokenLinksTo( $title_obj->getPrefixedDBkey() );
- }
-
- # Clear parser cache (not really used)
- if ( $wgEnableParserCache ) {
- OutputPage::parsercacheClearBrokenLinksTo( $title_obj->getPrefixedDBkey() );
- }
+ LinkCache::linksccClearBrokenLinksTo( $title_obj->getPrefixedDBkey() );
}
/* static */ function onArticleDelete($title_obj){
- global $wgEnablePersistentLC, $wgEnableParserCache;
- if ( $wgEnablePersistentLC ) {
- LinkCache::linksccClearLinksTo( $title_obj->getArticleID() );
- }
- if ( $wgEnableParserCache ) {
- OutputPage::parsercacheClearLinksTo( $title_obj->getArticleID() );
- }
+ LinkCache::linksccClearLinksTo( $title_obj->getArticleID() );
}
/* static */ function onArticleEdit($title_obj){
- global $wgEnablePersistentLC, $wgEnableParserCache;
- if ( $wgEnablePersistentLC ) {
- LinkCache::linksccClearPage( $title_obj->getArticleID() );
- }
- if ( $wgEnableParserCache ) {
- OutputPage::parsercacheClearPage( $title_obj->getArticleID(), $title_obj->getNamespace() );
- }
+ LinkCache::linksccClearPage( $title_obj->getArticleID() );
}
}
diff --git a/includes/Block.php b/includes/Block.php
index d98b07baebb7..e8a53e0efdd3 100644
--- a/includes/Block.php
+++ b/includes/Block.php
@@ -15,8 +15,8 @@ class Block
/* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry;
/* private */ var $mNetworkBits, $mIntegerAddr;
- function Block( $address = "", $user = "", $by = 0, $reason = "",
- $timestamp = "" , $auto = 0, $expiry = "" )
+ function Block( $address = '', $user = '', $by = 0, $reason = '',
+ $timestamp = '' , $auto = 0, $expiry = '' )
{
$this->mAddress = $address;
$this->mUser = $user;
@@ -38,18 +38,22 @@ class Block
function clear()
{
- $mAddress = $mReason = $mTimestamp = "";
+ $mAddress = $mReason = $mTimestamp = '';
$mUser = $mBy = 0;
}
# Get a ban from the DB, with either the given address or the given username
- function load( $address, $user = 0, $killExpired = true )
+ function load( $address = "", $user = 0, $killExpired = true )
{
- $fname = "Block::load";
+ $fname = 'Block::load';
$ret = false;
$killed = false;
- if ( 0 == $user ) {
+ if ( 0 == $user && $address=="" ) {
+ $sql = "SELECT * from ipblocks";
+ } elseif ($address=="") {
+ $sql = "SELECT * FROM ipblocks WHERE ipb_user={$user}";
+ } elseif ($user=="") {
$sql = "SELECT * FROM ipblocks WHERE ipb_address='" . wfStrencode( $address ) . "'";
} else {
$sql = "SELECT * FROM ipblocks WHERE (ipb_address='" . wfStrencode( $address ) .
@@ -109,7 +113,7 @@ class Block
function initialiseRange()
{
if ( $this->mUser == 0 ) {
- $rangeParts = explode( "/", $this->mAddress );
+ $rangeParts = explode( '/', $this->mAddress );
if ( count( $rangeParts ) == 2 ) {
$this->mNetworkBits = $rangeParts[1];
} else {
@@ -125,8 +129,8 @@ class Block
# Callback with a Block object for every block
/*static*/ function enumBlocks( $callback, $tag, $killExpired = true )
{
- $sql = "SELECT * FROM ipblocks ORDER BY ipb_timestamp DESC";
- $res = wfQuery( $sql, DB_READ, "Block::enumBans" );
+ $sql = 'SELECT * FROM ipblocks ORDER BY ipb_timestamp DESC';
+ $res = wfQuery( $sql, DB_READ, 'Block::enumBans' );
$block = new Block();
while ( $row = wfFetchObject( $res ) ) {
@@ -144,25 +148,25 @@ class Block
function delete()
{
- $fname = "Block::delete";
+ $fname = 'Block::delete';
if ( $this->mAddress == "" ) {
$sql = "DELETE FROM ipblocks WHERE ipb_id={$this->mId}";
} else {
$sql = "DELETE FROM ipblocks WHERE ipb_address='" .
wfStrencode( $this->mAddress ) . "'";
}
- wfQuery( $sql, DB_WRITE, "Block::delete" );
+ wfQuery( $sql, DB_WRITE, 'Block::delete' );
$this->clearCache();
}
function insert()
{
- $sql = "INSERT INTO ipblocks
- (ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto, ipb_expiry )
- VALUES ('" . wfStrencode( $this->mAddress ) . "', {$this->mUser}, {$this->mBy}, '" .
+ $sql = 'INSERT INTO ipblocks ' .
+ '(ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto, ipb_expiry )' .
+ "VALUES ('" . wfStrencode( $this->mAddress ) . "', {$this->mUser}, {$this->mBy}, '" .
wfStrencode( $this->mReason ) . "','{$this->mTimestamp}', {$this->mAuto}, '{$this->mExpiry}')";
- wfQuery( $sql, DB_WRITE, "Block::insert" );
+ wfQuery( $sql, DB_WRITE, 'Block::insert' );
$this->clearCache();
}
@@ -188,7 +192,7 @@ class Block
function isValid()
{
- return $this->mAddress != "";
+ return $this->mAddress != '';
}
function updateTimestamp()
@@ -197,10 +201,10 @@ class Block
$this->mTimestamp = wfTimestampNow();
$this->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
- wfQuery( "UPDATE ipblocks SET " .
+ wfQuery( 'UPDATE ipblocks SET ' .
"ipb_timestamp='" . $this->mTimestamp . "', " .
"ipb_expiry='" . $this->mExpiry . "' " .
- "WHERE ipb_address='" . wfStrencode( $this->mAddress ) . "'", DB_WRITE, "Block::updateTimestamp" );
+ "WHERE ipb_address='" . wfStrencode( $this->mAddress ) . "'", DB_WRITE, 'Block::updateTimestamp' );
$this->clearCache();
}
@@ -232,7 +236,7 @@ class Block
/* static */ function normaliseRange( $range )
{
- $parts = explode( "/", $range );
+ $parts = explode( '/', $range );
if ( count( $parts ) == 2 ) {
$shift = 32 - $parts[1];
$ipint = ip2long( $parts[0] );
diff --git a/includes/BlockCache.php b/includes/BlockCache.php
index 5b65bdc20a56..8b49a0142c13 100644
--- a/includes/BlockCache.php
+++ b/includes/BlockCache.php
@@ -7,15 +7,15 @@ class BlockCache
{
var $mData = false, $mMemcKey;
- function BlockCache( $deferLoad = false, $dbName = "" )
+ function BlockCache( $deferLoad = false, $dbName = '' )
{
global $wgDBname;
- if ( $dbName == "" ) {
+ if ( $dbName == '' ) {
$dbName = $wgDBname;
}
- $this->mMemcKey = "$dbName:ipblocks";
+ $this->mMemcKey = $dbName.':ipblocks';
if ( !$deferLoad ) {
$this->load();
@@ -36,10 +36,10 @@ class BlockCache
}
}
- if ( $this->mData === false || is_null( $this->mData ) ) {
+ if ( !is_array( $this->mData ) ) {
# Load from DB
$this->mData = array();
- Block::enumBlocks( "wfBlockCacheInsert", "" ); # Calls $this->insert()
+ Block::enumBlocks( 'wfBlockCacheInsert', '' ); # Calls $this->insert()
}
if ( $saveMemc ) {
@@ -78,7 +78,7 @@ class BlockCache
if ( $blocked ) {
# Clear low order bits
if ( $networkBits != 32 ) {
- $ip .= "/$networkBits";
+ $ip .= '/'.$networkBits;
$ip = Block::normaliseRange( $ip );
}
$block = new Block();
diff --git a/includes/CacheManager.php b/includes/CacheManager.php
index 5ba6ec7318e4..e85f69d94bc7 100644
--- a/includes/CacheManager.php
+++ b/includes/CacheManager.php
@@ -11,14 +11,14 @@
# $wgFileCacheDirectory
# $wgUseGzip
-require_once( "Title.php" );
+require_once( 'Title.php' );
class CacheManager {
var $mTitle, $mFileCache;
function CacheManager( &$title ) {
$this->mTitle =& $title;
- $this->mFileCache = "";
+ $this->mFileCache = '';
}
function fileCacheName() {
@@ -27,14 +27,14 @@ class CacheManager {
$hash = md5( $key = $this->mTitle->getDbkey() );
if( $this->mTitle->getNamespace() )
$key = $wgLang->getNsText( $this->mTitle->getNamespace() ) . ":" . $key;
- $key = str_replace( ".", "%2E", urlencode( $key ) );
+ $key = str_replace( '.', '%2E', urlencode( $key ) );
$hash1 = substr( $hash, 0, 1 );
$hash2 = substr( $hash, 0, 2 );
$this->mFileCache = "{$wgFileCacheDirectory}/{$hash1}/{$hash2}/{$key}.html";
if($this->useGzip())
- $this->mFileCache .= ".gz";
+ $this->mFileCache .= '.gz';
wfDebug( " fileCacheName() - {$this->mFileCache}\n" );
}
@@ -75,7 +75,7 @@ class CacheManager {
function fetchPageText() {
if( $this->useGzip() ) {
/* Why is there no gzfile_get_contents() or gzdecode()? */
- return implode( "", gzfile( $this->fileCacheName() ) );
+ return implode( '', gzfile( $this->fileCacheName() ) );
} else {
return $this->fetchRawText();
}
@@ -91,7 +91,7 @@ class CacheManager {
if( $this->useGzip() ) {
if( wfClientAcceptsGzip() ) {
- header( "Content-Encoding: gzip" );
+ header( 'Content-Encoding: gzip' );
} else {
/* Send uncompressed */
readgzfile( $filename );
@@ -103,38 +103,38 @@ class CacheManager {
function checkCacheDirs() {
$filename = $this->fileCacheName();
- $mydir2=substr($filename,0,strrpos($filename,"/")); # subdirectory level 2
- $mydir1=substr($mydir2,0,strrpos($mydir2,"/")); # subdirectory level 1
+ $mydir2=substr($filename,0,strrpos($filename,'/')); # subdirectory level 2
+ $mydir1=substr($mydir2,0,strrpos($mydir2,'/')); # subdirectory level 1
if(!file_exists($mydir1)) { mkdir($mydir1,0775); } # create if necessary
if(!file_exists($mydir2)) { mkdir($mydir2,0775); }
}
function saveToFileCache( $text ) {
- if(strcmp($text,"") == 0) return "";
+ if(strcmp($text,'') == 0) return '';
wfDebug(" saveToFileCache()\n", false);
$this->checkCacheDirs();
- $f = fopen( $this->fileCacheName(), "w" );
+ $f = fopen( $this->fileCacheName(), 'w' );
if($f) {
$now = wfTimestampNow();
if( $this->useGzip() ) {
- $rawtext = str_replace( "</html>",
- "<!-- Cached/compressed $now -->\n</html>",
+ $rawtext = str_replace( '</html>',
+ '<!-- Cached/compressed '.$now." -->\n</html>",
$text );
$text = gzencode( $rawtext );
} else {
- $text = str_replace( "</html>",
- "<!-- Cached $now -->\n</html>",
+ $text = str_replace( '</html>',
+ '<!-- Cached '.$now." -->\n</html>",
$text );
}
fwrite( $f, $text );
fclose( $f );
if( $this->useGzip() ) {
if( wfClientAcceptsGzip() ) {
- header( "Content-Encoding: gzip" );
+ header( 'Content-Encoding: gzip' );
return $text;
} else {
return $rawtext;
diff --git a/includes/Database.php b/includes/Database.php
index d84625492f8e..f3824858133f 100644
--- a/includes/Database.php
+++ b/includes/Database.php
@@ -1,11 +1,10 @@
<?php
-require_once( "FulltextStoplist.php" );
+# $Id$
+# This file deals with MySQL interface functions
+# and query specifics/optimisations
+#
require_once( "CacheManager.php" );
-define( "DB_READ", -1 );
-define( "DB_WRITE", -2 );
-define( "DB_LAST", -3 );
-
define( "LIST_COMMA", 0 );
define( "LIST_AND", 1 );
define( "LIST_SET", 2 );
@@ -36,7 +35,7 @@ class Database {
# Output page, used for reporting errors
# FALSE means discard output
- function &setOutputPage( &$out ) { return wfSetRef( $this->mOut, $out ); }
+ function &setOutputPage( &$out ) { $this->mOut =& $out; }
# Boolean, controls output of large amounts of debug information
function setDebug( $debug ) { return wfSetVar( $this->mDebug, $debug ); }
@@ -90,6 +89,12 @@ class Database {
{
global $wgEmergencyContact;
+ # Test for missing mysql.so
+ # Otherwise we get a suppressed fatal error, which is very hard to track down
+ if ( !function_exists( 'mysql_connect' ) ) {
+ die( "MySQL functions missing, have you compiled PHP with the --with-mysql option?\n" );
+ }
+
$this->close();
$this->mServer = $server;
$this->mUser = $user;
@@ -140,10 +145,11 @@ class Database {
{
if ( $this->mFailFunction ) {
if ( !is_int( $this->mFailFunction ) ) {
- $this->$mFailFunction( $this );
+ $ff = $this->mFailFunction;
+ $ff( $this, mysql_error() );
}
} else {
- wfEmergencyAbort( $this );
+ wfEmergencyAbort( $this, mysql_error() );
}
}
@@ -151,7 +157,7 @@ class Database {
# If errors are explicitly ignored, returns success
function query( $sql, $fname = "" )
{
- global $wgProfiling;
+ global $wgProfiling, $wgCommandLineMode;
if ( $wgProfiling ) {
# generalizeSQL will probably cut down the query to reasonable
@@ -174,13 +180,21 @@ class Database {
}
if ( false === $ret ) {
+ $error = mysql_error( $this->mConn );
+ $errno = mysql_errno( $this->mConn );
if( $this->mIgnoreErrors ) {
- wfDebug("SQL ERROR (ignored): " . mysql_error( $this->mConn ) . "\n");
+ wfDebug("SQL ERROR (ignored): " . $error . "\n");
} else {
- wfDebug("SQL ERROR: " . mysql_error( $this->mConn ) . "\n");
- if ( $this->mOut ) {
+ wfDebug("SQL ERROR: " . $error . "\n");
+ if ( $wgCommandLineMode ) {
+ wfDebugDieBacktrace( "A database error has occurred\n" .
+ "Query: $sql\n" .
+ "Function: $fname\n" .
+ "Error: $errno $error\n"
+ );
+ } elseif ( $this->mOut ) {
// this calls wfAbruptExit()
- $this->mOut->databaseError( $fname, $this );
+ $this->mOut->databaseError( $fname, $sql, $error, $errno );
}
}
}
@@ -204,6 +218,15 @@ class Database {
}
return $row;
}
+
+ function fetchRow( $res ) {
+ @$row = mysql_fetch_array( $res );
+ if (mysql_errno() ) {
+ wfDebugDieBacktrace( "SQL error: " . htmlspecialchars( mysql_error() ) );
+ }
+ return $row;
+ }
+
function numRows( $res ) {
@$n = mysql_num_rows( $res );
if( mysql_errno() ) {
@@ -254,8 +277,12 @@ class Database {
function getArray( $table, $vars, $conds, $fname = "Database::getArray" )
{
$vars = implode( ",", $vars );
- $where = Database::makeList( $conds, LIST_AND );
- $sql = "SELECT $vars FROM $table WHERE $where LIMIT 1";
+ if ( $conds !== false ) {
+ $where = Database::makeList( $conds, LIST_AND );
+ $sql = "SELECT $vars FROM $table WHERE $where LIMIT 1";
+ } else {
+ $sql = "SELECT $vars FROM $table LIMIT 1";
+ }
$res = $this->query( $sql, $fname );
if ( $res === false || !$this->numRows( $res ) ) {
return false;
@@ -314,7 +341,10 @@ class Database {
# If errors are explicitly ignored, returns NULL on failure
function indexExists( $table, $index, $fname = "Database::indexExists" )
{
- $sql = "SHOW INDEXES FROM $table";
+ # SHOW INDEX works in MySQL 3.23.58, but SHOW INDEXES does not.
+ # SHOW INDEX should work for 3.x and up:
+ # http://dev.mysql.com/doc/mysql/en/SHOW_INDEX.html
+ $sql = "SHOW INDEX FROM $table";
$res = $this->query( $sql, DB_READ, $fname );
if ( !$res ) {
return NULL;
@@ -334,6 +364,7 @@ class Database {
function tableExists( $table )
{
$old = $this->mIgnoreErrors;
+ $this->mIgnoreErrors = true;
$res = $this->query( "SELECT 1 FROM $table LIMIT 1" );
$this->mIgnoreErrors = $old;
if( $res ) {
@@ -441,12 +472,18 @@ class Database {
/* Standard fail function, called by default when a connection cannot be established
Displays the file cache if possible */
-function wfEmergencyAbort( &$conn ) {
+function wfEmergencyAbort( &$conn, $error ) {
global $wgTitle, $wgUseFileCache, $title, $wgInputEncoding, $wgSiteNotice, $wgOutputEncoding;
- header( "Content-type: text/html; charset=$wgOutputEncoding" );
+ if( !headers_sent() ) {
+ header( "HTTP/1.0 500 Internal Server Error" );
+ header( "Content-type: text/html; charset=$wgOutputEncoding" );
+ /* Don't cache error pages! They cause no end of trouble... */
+ header( "Cache-control: none" );
+ header( "Pragma: nocache" );
+ }
$msg = $wgSiteNotice;
- if($msg == "") $msg = wfMsgNoDB( "noconnect" );
+ if($msg == "") $msg = wfMsgNoDB( "noconnect", $error );
$text = $msg;
if($wgUseFileCache) {
@@ -478,9 +515,6 @@ function wfEmergencyAbort( &$conn ) {
}
}
- /* Don't cache error pages! They cause no end of trouble... */
- header( "Cache-control: none" );
- header( "Pragma: nocache" );
echo $text;
wfAbruptExit();
}
@@ -515,4 +549,9 @@ function wfInvertTimestamp( $ts ) {
"9876543210"
);
}
+
+function wfLimitResult( $limit, $offset ) {
+ return " LIMIT ".(is_numeric($offset)?"{$offset},":"")."{$limit} ";
+}
+
?>
diff --git a/includes/DatabaseFunctions.php b/includes/DatabaseFunctions.php
index 90bb40f19370..0169b9ff5eb3 100644
--- a/includes/DatabaseFunctions.php
+++ b/includes/DatabaseFunctions.php
@@ -1,4 +1,5 @@
<?php
+# $Id$
# Backwards compatibility wrapper for Database.php
@@ -7,53 +8,55 @@
# the load balancer will finally call Database, which will
# represent a single connection
-# NB: This file follows a connect on demand scheme. Do
-# not access the $wgDatabase variable directly unless
-# you intend to set it. Use wfGetDB().
+# Note: $wgDatabase has ceased to exist. Destroy all references.
+
+$wgIsMySQL=false;
+$wgIsPg=false;
+
+if ($wgDBtype=="mysql") {
+ require_once( "Database.php" );
+ $wgIsMySQL=true;
+} elseif ($wgDBtype=="pgsql") {
+ require_once( "DatabasePostgreSQL.php" );
+ $wgIsPg=true;
+}
-require_once( "Database.php" );
-# Query the database
-# $db: DB_READ = -1 read from slave (or only server)
-# DB_WRITE = -2 write to master (or only server)
-# 0,1,2,... query a database with a specific index
-# Replication is not actually implemented just yet
# Usually aborts on failure
# If errors are explicitly ignored, returns success
function wfQuery( $sql, $db, $fname = "" )
{
- global $wgDatabase, $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname,
- $wgDebugDumpSql, $wgBufferSQLResults, $wgIgnoreSQLErrors;
-
+ global $wgOut;
if ( !is_numeric( $db ) ) {
# Someone has tried to call this the old way
$wgOut->fatalError( wfMsgNoDB( "wrong_wfQuery_params", $db, $sql ) );
}
-
- $db =& wfGetDB();
- return $db->query( $sql, $fname );
+ $c =& wfGetDB( $db );
+ if ( $c !== false ) {
+ return $c->query( $sql, $fname );
+ } else {
+ return false;
+ }
}
-# Connect on demand
-function &wfGetDB()
+function &wfGetDB( $db = DB_LAST )
{
- global $wgDatabase, $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname,
- $wgDebugDumpSql, $wgBufferSQLResults, $wgIgnoreSQLErrors;
- if ( !$wgDatabase ) {
- $wgDatabase = Database::newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword,
- $wgDBname, false, $wgDebugDumpSql, $wgBufferSQLResults, $wgIgnoreSQLErrors );
- }
- return $wgDatabase;
+ global $wgLoadBalancer;
+ return $wgLoadBalancer->getConnection( $db );
}
# Turns buffering of SQL result sets on (true) or off (false). Default is
# "on" and it should not be changed without good reasons.
# Returns the previous state.
-function wfBufferSQLResults( $newstate )
+function wfBufferSQLResults( $newstate, $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->setBufferResults( $newstate );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->setBufferResults( $newstate );
+ } else {
+ return NULL;
+ }
}
# Turns on (false) or off (true) the automatic generation and sending
@@ -63,117 +66,206 @@ function wfBufferSQLResults( $newstate )
# situation as appropriate.
# Returns the previous state.
-function wfIgnoreSQLErrors( $newstate )
+function wfIgnoreSQLErrors( $newstate, $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->setIgnoreErrors( $newstate );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->setIgnoreErrors( $newstate );
+ } else {
+ return NULL;
+ }
}
-function wfFreeResult( $res )
+function wfFreeResult( $res, $dbi = DB_LAST )
{
- $db =& wfGetDB();
- $db->freeResult( $res );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ $db->freeResult( $res );
+ return true;
+ } else {
+ return false;
+ }
}
-function wfFetchObject( $res )
+function wfFetchObject( $res, $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->fetchObject( $res );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->fetchObject( $res, $dbi = DB_LAST );
+ } else {
+ return false;
+ }
+}
+
+function wfFetchRow( $res, $dbi = DB_LAST )
+{
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->fetchRow ( $res, $dbi = DB_LAST );
+ } else {
+ return false;
+ }
}
-function wfNumRows( $res )
+function wfNumRows( $res, $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->numRows( $res );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->numRows( $res, $dbi = DB_LAST );
+ } else {
+ return false;
+ }
}
-function wfNumFields( $res )
+function wfNumFields( $res, $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->numFields( $res );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->numFields( $res );
+ } else {
+ return false;
+ }
}
-function wfFieldName( $res, $n )
+function wfFieldName( $res, $n, $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->fieldName( $res, $n );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->fieldName( $res, $n, $dbi = DB_LAST );
+ } else {
+ return false;
+ }
}
-function wfInsertId()
+function wfInsertId( $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->insertId();
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->insertId();
+ } else {
+ return false;
+ }
}
-function wfDataSeek( $res, $row )
+
+function wfDataSeek( $res, $row, $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->dataSeek( $res, $row );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->dataSeek( $res, $row );
+ } else {
+ return false;
+ }
}
-function wfLastErrno()
+function wfLastErrno( $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->lastErrno();
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->lastErrno();
+ } else {
+ return false;
+ }
}
-function wfLastError()
+function wfLastError( $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->lastError();
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->lastError();
+ } else {
+ return false;
+ }
}
-function wfAffectedRows()
+function wfAffectedRows( $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->affectedRows();
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->affectedRows();
+ } else {
+ return false;
+ }
}
-function wfLastDBquery()
+function wfLastDBquery( $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->lastQuery();
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->lastQuery();
+ } else {
+ return false;
+ }
}
-function wfSetSQL( $table, $var, $value, $cond )
+function wfSetSQL( $table, $var, $value, $cond, $dbi = DB_WRITE )
{
- $db =& wfGetDB();
- return $db->set( $table, $var, $value, $cond );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->set( $table, $var, $value, $cond );
+ } else {
+ return false;
+ }
}
-function wfGetSQL( $table, $var, $cond )
+function wfGetSQL( $table, $var, $cond="", $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->get( $table, $var, $cond );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->get( $table, $var, $cond );
+ } else {
+ return false;
+ }
}
-function wfFieldExists( $table, $field )
+function wfFieldExists( $table, $field, $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->fieldExists( $table, $field );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->fieldExists( $table, $field );
+ } else {
+ return false;
+ }
}
-function wfIndexExists( $table, $index )
+function wfIndexExists( $table, $index, $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->indexExists( $table, $index );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->indexExists( $table, $index );
+ } else {
+ return false;
+ }
}
-function wfInsertArray( $table, $array )
+function wfInsertArray( $table, $array, $fname = "wfInsertArray", $dbi = DB_WRITE )
{
- $db =& wfGetDB();
- return $db->insertArray( $table, $array );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->insertArray( $table, $array, $fname );
+ } else {
+ return false;
+ }
}
-function wfGetArray( $table, $vars, $conds, $fname = "wfGetArray" )
+function wfGetArray( $table, $vars, $conds, $fname = "wfGetArray", $dbi = DB_LAST )
{
- $db =& wfGetDB();
- return $db->getArray( $table, $vars, $conds, $fname );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->getArray( $table, $vars, $conds, $fname );
+ } else {
+ return false;
+ }
}
-function wfUpdateArray( $table, $values, $conds, $fname = "wfUpdateArray" )
+function wfUpdateArray( $table, $values, $conds, $fname = "wfUpdateArray", $dbi = DB_WRITE )
{
- $db =& wfGetDB();
- $db->updateArray( $table, $values, $conds, $fname );
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ $db->updateArray( $table, $values, $conds, $fname );
+ return true;
+ } else {
+ return false;
+ }
}
?>
diff --git a/includes/DatabasePostgreSQL.php b/includes/DatabasePostgreSQL.php
new file mode 100644
index 000000000000..f9add198cc75
--- /dev/null
+++ b/includes/DatabasePostgreSQL.php
@@ -0,0 +1,549 @@
+<?php
+# $Id$
+#
+# DO NOT USE !!! Unless you want to help developping it.
+#
+# This file is an attempt to port the mysql database layer to postgreSQL. The
+# only thing done so far is s/mysql/pg/ and dieing if function haven't been
+# ported.
+#
+# As said brion 07/06/2004 :
+# "table definitions need to be changed. fulltext index needs to work differently
+# things that use the last insert id need to be changed. Probably other things
+# need to be changed. various semantics may be different."
+#
+# Hashar
+
+require_once( "FulltextStoplist.php" );
+require_once( "CacheManager.php" );
+
+define( "DB_READ", -1 );
+define( "DB_WRITE", -2 );
+define( "DB_LAST", -3 );
+
+define( "LIST_COMMA", 0 );
+define( "LIST_AND", 1 );
+define( "LIST_SET", 2 );
+
+class Database {
+
+#------------------------------------------------------------------------------
+# Variables
+#------------------------------------------------------------------------------
+ /* private */ var $mLastQuery = "";
+ /* private */ var $mBufferResults = true;
+ /* private */ var $mIgnoreErrors = false;
+
+ /* private */ var $mServer, $mUser, $mPassword, $mConn, $mDBname;
+ /* private */ var $mOut, $mDebug, $mOpened = false;
+
+ /* private */ var $mFailFunction;
+ /* private */ var $mLastResult;
+
+#------------------------------------------------------------------------------
+# Accessors
+#------------------------------------------------------------------------------
+ # Set functions
+ # These set a variable and return the previous state
+
+ # Fail function, takes a Database as a parameter
+ # Set to false for default, 1 for ignore errors
+ function setFailFunction( $function ) { return wfSetVar( $this->mFailFunction, $function ); }
+
+ # Output page, used for reporting errors
+ # FALSE means discard output
+ function &setOutputPage( &$out ) { $this->mOut =& $out; }
+
+ # Boolean, controls output of large amounts of debug information
+ function setDebug( $debug ) { return wfSetVar( $this->mDebug, $debug ); }
+
+ # Turns buffering of SQL result sets on (true) or off (false). Default is
+ # "on" and it should not be changed without good reasons.
+ function setBufferResults( $buffer ) { return wfSetVar( $this->mBufferResults, $buffer ); }
+
+ # Turns on (false) or off (true) the automatic generation and sending
+ # of a "we're sorry, but there has been a database error" page on
+ # database errors. Default is on (false). When turned off, the
+ # code should use wfLastErrno() and wfLastError() to handle the
+ # situation as appropriate.
+ function setIgnoreErrors( $ignoreErrors ) { return wfSetVar( $this->mIgnoreErrors, $ignoreErrors ); }
+
+ # Get functions
+
+ function lastQuery() { return $this->mLastQuery; }
+ function isOpen() { return $this->mOpened; }
+
+#------------------------------------------------------------------------------
+# Other functions
+#------------------------------------------------------------------------------
+
+ function Database()
+ {
+ global $wgOut;
+ # Can't get a reference if it hasn't been set yet
+ if ( !isset( $wgOut ) ) {
+ $wgOut = NULL;
+ }
+ $this->mOut =& $wgOut;
+
+ }
+
+ /* static */ function newFromParams( $server, $user, $password, $dbName,
+ $failFunction = false, $debug = false, $bufferResults = true, $ignoreErrors = false )
+ {
+ $db = new Database;
+ $db->mFailFunction = $failFunction;
+ $db->mIgnoreErrors = $ignoreErrors;
+ $db->mDebug = $debug;
+ $db->mBufferResults = $bufferResults;
+ $db->open( $server, $user, $password, $dbName );
+ return $db;
+ }
+
+ # Usually aborts on failure
+ # If the failFunction is set to a non-zero integer, returns success
+ function open( $server, $user, $password, $dbName )
+ {
+ global $wgEmergencyContact;
+
+ $this->close();
+ $this->mServer = $server;
+ $this->mUser = $user;
+ $this->mPassword = $password;
+ $this->mDBname = $dbName;
+
+ $success = false;
+
+
+ if ( "" != $dbName ) {
+ # start a database connection
+ @$this->mConn = pg_connect("host=$server dbname=$dbName user=$user password=$password");
+ if ( $this->mConn == false ) {
+ wfDebug( "DB connection error\n" );
+ wfDebug( "Server: $server, Database: $dbName, User: $user, Password: " . substr( $password, 0, 3 ) . "...\n" );
+ wfDebug( $this->lastError()."\n" );
+ } else {
+ $this->mOpened = true;
+ }
+ }
+ return $this->mConn;
+ }
+
+ # Closes a database connection, if it is open
+ # Returns success, true if already closed
+ function close()
+ {
+ $this->mOpened = false;
+ if ( $this->mConn ) {
+ return pg_close( $this->mConn );
+ } else {
+ return true;
+ }
+ }
+
+ /* private */ function reportConnectionError( $msg = "")
+ {
+ if ( $this->mFailFunction ) {
+ if ( !is_int( $this->mFailFunction ) ) {
+ $this->$mFailFunction( $this );
+ }
+ } else {
+ wfEmergencyAbort( $this );
+ }
+ }
+
+ # Usually aborts on failure
+ # If errors are explicitly ignored, returns success
+ function query( $sql, $fname = "" )
+ {
+ global $wgProfiling;
+
+ if ( $wgProfiling ) {
+ # generalizeSQL will probably cut down the query to reasonable
+ # logging size most of the time. The substr is really just a sanity check.
+ $profName = "query: " . substr( Database::generalizeSQL( $sql ), 0, 255 );
+ wfProfileIn( $profName );
+ }
+
+ $this->mLastQuery = $sql;
+
+ if ( $this->mDebug ) {
+ $sqlx = substr( $sql, 0, 500 );
+ $sqlx = wordwrap(strtr($sqlx,"\t\n"," "));
+ wfDebug( "SQL: $sqlx\n" );
+ }
+
+ $ret = pg_query( $this->mConn , $sql);
+ $this->mLastResult = $ret;
+ if ( false == $ret ) {
+ $error = pg_last_error( $this->mConn );
+ // TODO FIXME : no error number function in postgre
+ // $errno = mysql_errno( $this->mConn );
+ if( $this->mIgnoreErrors ) {
+ wfDebug("SQL ERROR (ignored): " . $error . "\n");
+ } else {
+ wfDebug("SQL ERROR: " . $error . "\n");
+ if ( $this->mOut ) {
+ // this calls wfAbruptExit()
+ $this->mOut->databaseError( $fname, $sql, $error, 0 );
+ }
+ }
+ }
+
+ if ( $wgProfiling ) {
+ wfProfileOut( $profName );
+ }
+ return $ret;
+ }
+
+ function freeResult( $res ) {
+ if ( !@pg_free_result( $res ) ) {
+ wfDebugDieBacktrace( "Unable to free PostgreSQL result\n" );
+ }
+ }
+ function fetchObject( $res ) {
+ @$row = pg_fetch_object( $res );
+ # FIXME: HACK HACK HACK HACK debug
+
+ # TODO:
+ # hashar : not sure if the following test really trigger if the object
+ # fetching failled.
+ if( pg_last_error($this->mConn) ) {
+ wfDebugDieBacktrace( "SQL error: " . htmlspecialchars( pg_last_error($this->mConn) ) );
+ }
+ return $row;
+ }
+
+ function fetchRow( $res ) {
+ @$row = pg_fetch_array( $res );
+ if( pg_last_error($this->mConn) ) {
+ wfDebugDieBacktrace( "SQL error: " . htmlspecialchars( pg_last_error($this->mConn) ) );
+ }
+ return $row;
+ }
+
+ function numRows( $res ) {
+ @$n = pg_num_rows( $res );
+ if( pg_last_error($this->mConn) ) {
+ wfDebugDieBacktrace( "SQL error: " . htmlspecialchars( pg_last_error($this->mConn) ) );
+ }
+ return $n;
+ }
+ function numFields( $res ) { return pg_num_fields( $res ); }
+ function fieldName( $res, $n ) { return pg_field_name( $res, $n ); }
+ // TODO FIXME: need to implement something here
+ function insertId() {
+ //return mysql_insert_id( $this->mConn );
+ wfDebugDieBacktrace( "Database::insertId() error : not implemented for postgre, use sequences" );
+ }
+ function dataSeek( $res, $row ) { return pg_result_seek( $res, $row ); }
+ function lastErrno() { return $this->lastError(); }
+ function lastError() { return pg_last_error(); }
+ function affectedRows() {
+ return pg_affected_rows( $this->mLastResult );
+ }
+
+ # Simple UPDATE wrapper
+ # Usually aborts on failure
+ # If errors are explicitly ignored, returns success
+ function set( $table, $var, $value, $cond, $fname = "Database::set" )
+ {
+ $sql = "UPDATE \"$table\" SET \"$var\" = '" .
+ wfStrencode( $value ) . "' WHERE ($cond)";
+ return !!$this->query( $sql, DB_WRITE, $fname );
+ }
+
+ # Simple SELECT wrapper, returns a single field, input must be encoded
+ # Usually aborts on failure
+ # If errors are explicitly ignored, returns FALSE on failure
+ function get( $table, $var, $cond, $fname = "Database::get" )
+ {
+ $from=$table?" FROM \"$table\" ":"";
+ $where=$cond?" WHERE ($cond)":"";
+
+ $sql = "SELECT $var $from $where";
+
+ $result = $this->query( $sql, DB_READ, $fname );
+
+ $ret = "";
+ if ( pg_num_rows( $result ) > 0 ) {
+ $s = pg_fetch_array( $result );
+ $ret = $s[0];
+ pg_free_result( $result );
+ }
+ return $ret;
+ }
+
+ # More complex SELECT wrapper, single row only
+ # Aborts or returns FALSE on error
+ # Takes an array of selected variables, and a condition map, which is ANDed
+ # e.g. getArray( "cur", array( "cur_id" ), array( "cur_namespace" => 0, "cur_title" => "Astronomy" ) )
+ # would return an object where $obj->cur_id is the ID of the Astronomy article
+ function getArray( $table, $vars, $conds, $fname = "Database::getArray" )
+ {
+ $vars = implode( ",", $vars );
+ $where = Database::makeList( $conds, LIST_AND );
+ $sql = "SELECT \"$vars\" FROM \"$table\" WHERE $where LIMIT 1";
+ $res = $this->query( $sql, $fname );
+ if ( $res === false || !$this->numRows( $res ) ) {
+ return false;
+ }
+ $obj = $this->fetchObject( $res );
+ $this->freeResult( $res );
+ return $obj;
+ }
+
+ # Removes most variables from an SQL query and replaces them with X or N for numbers.
+ # It's only slightly flawed. Don't use for anything important.
+ /* static */ function generalizeSQL( $sql )
+ {
+ # This does the same as the regexp below would do, but in such a way
+ # as to avoid crashing php on some large strings.
+ # $sql = preg_replace ( "/'([^\\\\']|\\\\.)*'|\"([^\\\\\"]|\\\\.)*\"/", "'X'", $sql);
+
+ $sql = str_replace ( "\\\\", "", $sql);
+ $sql = str_replace ( "\\'", "", $sql);
+ $sql = str_replace ( "\\\"", "", $sql);
+ $sql = preg_replace ("/'.*'/s", "'X'", $sql);
+ $sql = preg_replace ('/".*"/s', "'X'", $sql);
+
+ # All newlines, tabs, etc replaced by single space
+ $sql = preg_replace ( "/\s+/", " ", $sql);
+
+ # All numbers => N
+ $sql = preg_replace ('/-?[0-9]+/s', "N", $sql);
+
+ return $sql;
+ }
+
+ # Determines whether a field exists in a table
+ # Usually aborts on failure
+ # If errors are explicitly ignored, returns NULL on failure
+ function fieldExists( $table, $field, $fname = "Database::fieldExists" )
+ {
+ $res = $this->query( "DESCRIBE '$table'", DB_READ, $fname );
+ if ( !$res ) {
+ return NULL;
+ }
+
+ $found = false;
+
+ while ( $row = $this->fetchObject( $res ) ) {
+ if ( $row->Field == $field ) {
+ $found = true;
+ break;
+ }
+ }
+ return $found;
+ }
+
+ # Determines whether an index exists
+ # Usually aborts on failure
+ # If errors are explicitly ignored, returns NULL on failure
+ function indexExists( $table, $index, $fname = "Database::indexExists" )
+ {
+ $sql = "SELECT indexname FROM pg_indexes WHERE tablename='$table'";
+ $res = $this->query( $sql, DB_READ, $fname );
+ if ( !$res ) {
+ return NULL;
+ }
+
+ $found = false;
+
+ while ( $row = $this->fetchObject( $res ) ) {
+ if ( $row->Key_name == $index ) {
+ $found = true;
+ break;
+ }
+ }
+ return $found;
+ }
+
+ function tableExists( $table )
+ {
+ $old = $this->mIgnoreErrors;
+ $this->mIgnoreErrors = true;
+ $res = $this->query( "SELECT 1 FROM '$table' LIMIT 1" );
+ $this->mIgnoreErrors = $old;
+ if( $res ) {
+ $this->freeResult( $res );
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function fieldInfo( $table, $field )
+ {
+ $res = $this->query( "SELECT * FROM '$table' LIMIT 1" );
+ $n = pg_num_fields( $res );
+ for( $i = 0; $i < $n; $i++ ) {
+ // FIXME
+ wfDebugDieBacktrace( "Database::fieldInfo() error : mysql_fetch_field() not implemented for postgre" );
+ $meta = mysql_fetch_field( $res, $i );
+ if( $field == $meta->name ) {
+ return $meta;
+ }
+ }
+ return false;
+ }
+
+ # INSERT wrapper, inserts an array into a table
+ # Keys are field names, values are values
+ # Usually aborts on failure
+ # If errors are explicitly ignored, returns success
+ function insertArray( $table, $a, $fname = "Database::insertArray" )
+ {
+ $sql1 = "INSERT INTO \"$table\" (";
+ $sql2 = "VALUES (" . Database::makeList( $a );
+ $first = true;
+ foreach ( $a as $field => $value ) {
+ if ( !$first ) {
+ $sql1 .= ",";
+ }
+ $first = false;
+ $sql1 .= $field;
+ }
+ $sql = "$sql1) $sql2)";
+ return !!$this->query( $sql, $fname );
+ }
+
+ # A cross between insertArray and getArray, takes a condition array and a SET array
+ function updateArray( $table, $values, $conds, $fname = "Database::updateArray" )
+ {
+ $sql = "UPDATE '$table' SET " . $this->makeList( $values, LIST_SET );
+ $sql .= " WHERE " . $this->makeList( $conds, LIST_AND );
+ $this->query( $sql, $fname );
+ }
+
+ # Makes a wfStrencoded list from an array
+ # $mode: LIST_COMMA - comma separated, no field names
+ # LIST_AND - ANDed WHERE clause (without the WHERE)
+ # LIST_SET - comma separated with field names, like a SET clause
+ /* static */ function makeList( $a, $mode = LIST_COMMA )
+ {
+ $first = true;
+ $list = "";
+ foreach ( $a as $field => $value ) {
+ if ( !$first ) {
+ if ( $mode == LIST_AND ) {
+ $list .= " AND ";
+ } else {
+ $list .= ",";
+ }
+ } else {
+ $first = false;
+ }
+ if ( $mode == LIST_AND || $mode == LIST_SET ) {
+ $list .= "$field=";
+ }
+ if ( !is_numeric( $value ) ) {
+ $list .= "'" . wfStrencode( $value ) . "'";
+ } else {
+ $list .= $value;
+ }
+ }
+ return $list;
+ }
+
+ function startTimer( $timeout )
+ {
+ global $IP;
+ wfDebugDieBacktrace( "Database::startTimer() error : mysql_thread_id() not implemented for postgre" );
+ $tid = mysql_thread_id( $this->mConn );
+ exec( "php $IP/killthread.php $timeout $tid &>/dev/null &" );
+ }
+
+ function stopTimer()
+ {
+ }
+
+}
+
+#------------------------------------------------------------------------------
+# Global functions
+#------------------------------------------------------------------------------
+
+/* Standard fail function, called by default when a connection cannot be established
+ Displays the file cache if possible */
+function wfEmergencyAbort( &$conn ) {
+ global $wgTitle, $wgUseFileCache, $title, $wgInputEncoding, $wgSiteNotice, $wgOutputEncoding;
+
+ header( "Content-type: text/html; charset=$wgOutputEncoding" );
+ $msg = $wgSiteNotice;
+ if($msg == "") $msg = wfMsgNoDB( "noconnect" );
+ $text = $msg;
+
+ if($wgUseFileCache) {
+ if($wgTitle) {
+ $t =& $wgTitle;
+ } else {
+ if($title) {
+ $t = Title::newFromURL( $title );
+ } elseif (@$_REQUEST['search']) {
+ $search = $_REQUEST['search'];
+ echo wfMsgNoDB( "searchdisabled" );
+ echo wfMsgNoDB( "googlesearch", htmlspecialchars( $search ), $wgInputEncoding );
+ wfAbruptExit();
+ } else {
+ $t = Title::newFromText( wfMsgNoDB( "mainpage" ) );
+ }
+ }
+
+ $cache = new CacheManager( $t );
+ if( $cache->isFileCached() ) {
+ $msg = "<p style='color: red'><b>$msg<br />\n" .
+ wfMsgNoDB( "cachederror" ) . "</b></p>\n";
+
+ $tag = "<div id='article'>";
+ $text = str_replace(
+ $tag,
+ $tag . $msg,
+ $cache->fetchPageText() );
+ }
+ }
+
+ /* Don't cache error pages! They cause no end of trouble... */
+ header( "Cache-control: none" );
+ header( "Pragma: nocache" );
+ echo $text;
+ wfAbruptExit();
+}
+
+function wfStrencode( $s )
+{
+ return pg_escape_string( $s );
+}
+
+# Use PostgreSQL timestamp without timezone data type
+function wfTimestamp2Unix( $ts ) {
+ return gmmktime( ( (int)substr( $ts, 11, 2) ),
+ (int)substr( $ts, 14, 2 ), (int)substr( $ts, 17, 2 ),
+ (int)substr( $ts, 5, 2 ), (int)substr( $ts, 8, 2 ),
+ (int)substr( $ts, 0, 4 ) );
+}
+
+function wfUnix2Timestamp( $unixtime ) {
+ return gmdate( "Y-m-d H:i:s", $unixtime );
+}
+
+function wfTimestampNow() {
+ # return NOW
+ return gmdate( "Y-m-d H:i:s" );
+}
+
+# Sorting hack for MySQL 3, which doesn't use index sorts for DESC
+function wfInvertTimestamp( $ts ) {
+ $ts=preg_replace("/\D/","",$ts);
+ return strtr(
+ $ts,
+ "0123456789",
+ "9876543210"
+ );
+}
+
+function wfLimitResult( $limit, $offset ) {
+ return " LIMIT $limit ".(is_numeric($offset)?" OFFSET {$offset} ":"");
+}
+
+?>
diff --git a/includes/DateFormatter.php b/includes/DateFormatter.php
index e903f53daa79..45196512f5fe 100755
--- a/includes/DateFormatter.php
+++ b/includes/DateFormatter.php
@@ -18,7 +18,7 @@ define("DF_LAST", 8);
class DateFormatter
{
var $mSource, $mTarget;
- var $monthNames = "", $rxDM, $rxMD, $rxDMY, $rxYDM, $rxMDY, $rxYMD;
+ var $monthNames = '', $rxDM, $rxMD, $rxDMY, $rxYDM, $rxMDY, $rxYMD;
var $regexes, $pDays, $pMonths, $pYears;
var $rules, $xMonths;
@@ -58,24 +58,24 @@ class DateFormatter
# Extraction keys
# See the comments in replace() for the meaning of the letters
- $this->keys[DF_DMY] = "jFY";
- $this->keys[DF_YDM] = "Y jF";
- $this->keys[DF_MDY] = "FjY";
- $this->keys[DF_YMD] = "Y Fj";
- $this->keys[DF_DM] = "jF";
- $this->keys[DF_MD] = "Fj";
- $this->keys[DF_ISO1] = "ymd"; # y means ISO year
- $this->keys[DF_ISO2] = "ymd";
+ $this->keys[DF_DMY] = 'jFY';
+ $this->keys[DF_YDM] = 'Y jF';
+ $this->keys[DF_MDY] = 'FjY';
+ $this->keys[DF_YMD] = 'Y Fj';
+ $this->keys[DF_DM] = 'jF';
+ $this->keys[DF_MD] = 'Fj';
+ $this->keys[DF_ISO1] = 'ymd'; # y means ISO year
+ $this->keys[DF_ISO2] = 'ymd';
# Target date formats
- $this->targets[DF_DMY] = "[[F j|j F]] [[Y]]";
- $this->targets[DF_YDM] = "[[Y]], [[F j|j F]]";
- $this->targets[DF_MDY] = "[[F j]], [[Y]]";
- $this->targets[DF_YMD] = "[[Y]] [[F j]]";
- $this->targets[DF_DM] = "[[F j|j F]]";
- $this->targets[DF_MD] = "[[F j]]";
- $this->targets[DF_ISO1] = "[[Y|y]]-[[F j|m-d]]";
- $this->targets[DF_ISO2] = "[[y-m-d]]";
+ $this->targets[DF_DMY] = '[[F j|j F]] [[Y]]';
+ $this->targets[DF_YDM] = '[[Y]], [[F j|j F]]';
+ $this->targets[DF_MDY] = '[[F j]], [[Y]]';
+ $this->targets[DF_YMD] = '[[Y]] [[F j]]';
+ $this->targets[DF_DM] = '[[F j|j F]]';
+ $this->targets[DF_MD] = '[[F j]]';
+ $this->targets[DF_ISO1] = '[[Y|y]]-[[F j|m-d]]';
+ $this->targets[DF_ISO2] = '[[y-m-d]]';
# Rules
# pref source target
@@ -103,7 +103,7 @@ class DateFormatter
# Default
$this->mTarget = $i;
}
- $text = preg_replace_callback( $this->regexes[$i], "wfMainDateReplace", $text );
+ $text = preg_replace_callback( $this->regexes[$i], 'wfMainDateReplace', $text );
}
return $text;
}
@@ -123,7 +123,7 @@ class DateFormatter
$format = $this->targets[$this->mTarget];
# Construct new date
- $text = "";
+ $text = '';
$fail = false;
for ( $p=0; $p < strlen( $format ); $p++ ) {
@@ -131,7 +131,7 @@ class DateFormatter
switch ( $char ) {
case 'd': # ISO day of month
if ( is_null($bits['d']) ) {
- $text .= sprintf( "%02d", $bits['j'] );
+ $text .= sprintf( '%02d', $bits['j'] );
} else {
$text .= $bits['d'];
}
@@ -139,7 +139,7 @@ class DateFormatter
case 'm': # ISO month
if ( is_null($bits['m']) ) {
$m = $this->makeIsoMonth( $bits['F'] );
- if ( !$m || $m == "00" ) {
+ if ( !$m || $m == '00' ) {
$fail = true;
} else {
$text .= $m;
@@ -194,14 +194,14 @@ class DateFormatter
function getMonthRegex()
{
global $wgMonthNamesEn;
- return implode( "|", $wgMonthNamesEn );
+ return implode( '|', $wgMonthNamesEn );
}
# Makes an ISO month, e.g. 02, from a month name
function makeIsoMonth( $monthName )
{
$n = $this->xMonths[strtolower( $monthName )];
- return sprintf( "%02d", $n );
+ return sprintf( '%02d', $n );
}
function makeIsoYear( $year )
@@ -210,10 +210,10 @@ class DateFormatter
if ( substr( $year, -2 ) == 'BC' ) {
$num = IntVal(substr( $year, 0, -3 )) - 1;
# PHP bug note: sprintf( "%04d", -1 ) fails poorly
- $text = sprintf( "-%04d", $num );
+ $text = sprintf( '-%04d', $num );
} else {
- $text = sprintf( "%04d", $year );
+ $text = sprintf( '%04d', $year );
}
return $text;
}
@@ -221,7 +221,7 @@ class DateFormatter
function makeNormalYear( $iso )
{
if ( $iso{0} == '-' ) {
- $text = (IntVal( substr( $iso, 1 ) ) - 1) . " BC";
+ $text = (IntVal( substr( $iso, 1 ) ) - 1) . ' BC';
} else {
$text = IntVal( $iso );
}
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 52eb0b1ef1d8..0eaf809ba8ce 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -1,4 +1,5 @@
<?php
+# $Id$
# DO NOT EDIT THIS FILE!
# To customize your installation, edit "LocalSettings.php".
# Note that since all these string interpolations are expanded
@@ -6,27 +7,27 @@
# like $wgScriptPath, you must also localize everything that
# depends on it.
-$wgVersion = "1.3.0beta1";
+$wgVersion = '1.3.0beta4';
-$wgSitename = "MediaWiki"; # Please customize!
+$wgSitename = 'MediaWiki'; # Please customize!
$wgMetaNamespace = FALSE; # will be same as you set $wgSitename
# check if server use https:
-$wgProto = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") ? "https" : "http";
+$wgProto = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
if ( @$wgCommandLineMode ) {
- $wgServer = $wgProto."://localhost";
+ $wgServer = $wgProto.'://localhost';
} else {
- $wgServer = $wgProto."://" . $_SERVER["SERVER_NAME"];
- if( $_SERVER["SERVER_PORT"] != 80 ) $wgServer .= ":" . $_SERVER["SERVER_PORT"];
+ $wgServer = $wgProto.'://' . $_SERVER['SERVER_NAME'];
+ if( $_SERVER['SERVER_PORT'] != 80 ) $wgServer .= ":" . $_SERVER['SERVER_PORT'];
}
unset($wgProto);
-$wgScriptPath = "/wiki";
+$wgScriptPath = '/wiki';
# Whether to support URLs like index.php/Page_title
-$wgUsePathInfo = ( strpos( php_sapi_name(), "cgi" ) === false );
+$wgUsePathInfo = ( strpos( php_sapi_name(), 'cgi' ) === false );
# ATTN: Old installations used wiki.phtml and redirect.phtml -
# make sure that LocalSettings.php is correctly set!
@@ -44,25 +45,30 @@ $wgLogo = "{$wgUploadPath}/wiki.png";
$wgMathPath = "{$wgUploadPath}/math";
$wgMathDirectory = "{$wgUploadDirectory}/math";
$wgTmpDirectory = "{$wgUploadDirectory}/tmp";
-$wgEmergencyContact = "wikiadmin@" . getenv( "SERVER_NAME" );
-$wgPasswordSender = "Wikipedia Mail <apache@" . getenv( "SERVER_NAME" ) . ">";
+$wgEmergencyContact = 'wikiadmin@' . getenv( 'SERVER_NAME' );
+$wgPasswordSender = 'Wikipedia Mail <apache@' . getenv( 'SERVER_NAME' ) . '>';
# For using a direct (authenticated) SMTP server connection.
# "host" => 'SMTP domain', "IDHost" => 'domain for MessageID', "port" => "25", "auth" => true/false, "username" => user, "password" => password
$wgSMTP = false;
-# MySQL settings
+# Database settings
#
-$wgDBserver = "localhost";
-$wgDBname = "wikidb";
-$wgDBconnection = "";
-$wgDBuser = "wikiuser";
+$wgDBserver = 'localhost';
+$wgDBname = 'wikidb';
+$wgDBconnection = '';
+$wgDBuser = 'wikiuser';
+$wgDBtype = "mysql"; # "mysql" for working code and "pgsql" for development/broken code
+
+# Database load balancer
+$wgDBservers = false; # e.g. array(0 => "larousse", 1 => "pliny")
+$wgDBloads = false; # e.g. array(0 => 0.6, 1 => 0.4);
# Sysop SQL queries
$wgAllowSysopQueries = false; # Dangerous if not configured properly.
-$wgDBsqluser = "sqluser";
-$wgDBsqlpassword = "sqlpass";
-$wgDBpassword = "userpass";
+$wgDBsqluser = 'sqluser';
+$wgDBsqlpassword = 'sqlpass';
+$wgDBpassword = 'userpass';
$wgSqlLogFile = "{$wgUploadDirectory}/sqllog_mFhyRe6";
$wgDBminWordLen = 4;
@@ -85,27 +91,28 @@ $wgDBloads = false; # e.g. array(0.6, 0.4);
#
$wgMemCachedDebug = false; # Will be set to false in Setup.php, if the server isn't working
$wgUseMemCached = false;
-$wgMemCachedServers = array( "127.0.0.1:11000" );
+$wgMemCachedServers = array( '127.0.0.1:11000' );
$wgMemCachedDebug = false;
$wgSessionsInMemcached = false;
$wgLinkCacheMemcached = false; # Not fully tested
# Language settings
#
-$wgLanguageCode = "en";
+$wgLanguageCode = 'en';
$wgLanguageFile = false; # Filename of a language file generated by dumpMessages.php
$wgInterwikiMagic = true; # Treat language links as magic connectors, not inline links
-$wgInputEncoding = "ISO-8859-1";
-$wgOutputEncoding = "ISO-8859-1";
-$wgEditEncoding = "";
-$wgMimeType = "text/html";
-$wgDocType = "-//W3C//DTD XHTML 1.0 Transitional//EN";
-$wgDTD = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";
+$wgInputEncoding = 'ISO-8859-1'; # LanguageUtf8.php normally overrides this
+$wgOutputEncoding = 'ISO-8859-1'; # unless you set the next option to true:
+$wgUseLatin1 = false; # Enable ISO-8859-1 compatibility mode
+$wgEditEncoding = '';
+$wgMimeType = 'text/html';
+$wgDocType = '-//W3C//DTD XHTML 1.0 Transitional//EN';
+$wgDTD = 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd';
$wgUseDynamicDates = false; # Enable to allow rewriting dates in page text
# DOES NOT FORMAT CORRECTLY FOR MOST LANGUAGES
$wgAmericanDates = false; # Enable for English module to print dates
# as eg 'May 12' instead of '12 May'
-$wgLocalInterwiki = "w";
+$wgLocalInterwiki = 'w';
$wgShowIPinHeader = true; # For non-logged in users
$wgMaxNameChars = 32; # Maximum number of bytes in username
$wgInterwikiExpiry = 10800; # Expiry time for cache of interwiki table
@@ -115,8 +122,8 @@ $wgInterwikiExpiry = 10800; # Expiry time for cache of interwiki table
$wgUseDatabaseMessages = true;
$wgMsgCacheExpiry = 86400;
-$wgExtraSubtitle = "";
-$wgSiteSupportPage = "";
+$wgExtraSubtitle = '';
+$wgSiteSupportPage = '';
# Miscellaneous configuration settings
#
@@ -124,7 +131,7 @@ $wgReadOnlyFile = "{$wgUploadDirectory}/lock_yBgMBwiR";
# The debug log file should be not be publicly accessible if it is
# used, as it may contain private data.
-$wgDebugLogFile = "";
+$wgDebugLogFile = '';
$wgDebugRedirects = false;
$wgDebugComments = false;
@@ -142,6 +149,11 @@ $wgIgnoreSQLErrors = false;
# all articles in the category)
$wgUseCategoryMagic = true;
+# disable experimental dmoz-like category browsing. Output things like:
+# Encyclopedia > Music > Style of Music > Jazz
+# FIXME: need fixing
+$wgUseCategoryBrowser = false;
+
$wgEnablePersistentLC = false; # Persistent link cache in linkscc table; FAILS on MySQL 3.x
$wgCompressedPersistentLC = true; # use gzcompressed blobs
@@ -158,24 +170,26 @@ $wgHitcounterUpdateFreq = 1;
# User rights
$wgWhitelistEdit = false; # true = user must login to edit.
$wgWhitelistRead = false; # Pages anonymous user may see, like: = array ( ":Main_Page", "Special:Userlogin", "Wikipedia:Help");
-$wgWhitelistAccount = array ( "user" => 1, "sysop" => 1, "developer" => 1 );
+$wgWhitelistAccount = array ( 'user' => 1, 'sysop' => 1, 'developer' => 1 );
$wgSysopUserBans = false; # Allow sysops to ban logged-in users
$wgSysopRangeBans = false; # Allow sysops to ban IP ranges
-$wgDefaultBlockExpiry = "24 hours"; # default expiry time
+$wgDefaultBlockExpiry = '24 hours'; # default expiry time
# strtotime format, or "infinite" for an infinite block
$wgAutoblockExpiry = 86400; # Number of seconds before autoblock entries expire
$wgBlockOpenProxies = false; # Automatic open proxy test on edit
$wgProxyPorts = array( 80, 81, 1080, 3128, 6588, 8000, 8080, 8888, 65506 );
$wgProxyScriptPath = "$IP/proxy_check.php";
$wgProxyMemcExpiry = 86400;
-$wgProxyKey = "W1svekXc5u6lZllTZOwnzEk1nbs";
+$wgProxyKey = 'W1svekXc5u6lZllTZOwnzEk1nbs';
+$wgProxyList = array(); # big list of banned IP addresses, in the keys not the values
+$wgAccountCreationThrottle = 0; # Number of accounts each IP address may create, 0 to disable. Requires memcached
# Client-side caching:
$wgCachePages = true; # Allow client-side caching of pages
# Set this to current time to invalidate all prior cached pages.
# Affects both client- and server-side caching.
-$wgCacheEpoch = "20030516000000";
+$wgCacheEpoch = '20030516000000';
# Server-side caching:
# This will cache static pages for non-logged-in users
@@ -205,8 +219,8 @@ $wgCookieExpiration = 2592000;
# Set to set an explicit domain on the login cookies
# eg, "justthis.domain.org" or ".any.subdomain.net"
-$wgCookieDomain = "";
-$wgCookiePath = "/";
+$wgCookieDomain = '';
+$wgCookiePath = '/';
$wgDisableCookieCheck = false;
$wgAllowExternalImages = true;
@@ -220,18 +234,7 @@ $wgWLCacheTimeout = 3600; # The hour or so mentioned above
# convert (ImageMagick) installed and available in the PATH.
# Please see math/README for more information.
$wgUseTeX = false;
-$wgTexvc = "./math/texvc"; # Location of the texvc binary
-
-# Support for inline hieroglyphs, see http://aoineko.free.fr/ The
-# WikiHiero php files must be present in the same directory as the
-# rest of the mediawiki code, and WikiHiero must have been configured
-# with the correct image locations.
-$wgUseWikiHiero = false;
-
-# Support for inline timelines, see http://members.chello.nl/epzachte/Wikipedia/EasyTimeline/Introduction.htm
-# The Timeline php files must be present in the extension directory and you must have the
-# ploticus tool available, see http://ploticus.sourceforge.net/
-$wgUseTimeline = false;
+$wgTexvc = './math/texvc'; # Location of the texvc binary
# Profiling / debugging
$wgProfiling = false; # Enable for more detailed by-function times in debug log
@@ -253,11 +256,11 @@ $wgDisableAnonTalk = false;
# We can serve pages compressed in order to save bandwidth,
# but this will increase CPU usage.
# Requires zlib support enabled in PHP.
-$wgUseGzip = function_exists( "gzencode" );
+$wgUseGzip = function_exists( 'gzencode' );
# Path to the GNU diff3 utility. If the file doesn't exist,
# edit conflicts will fall back to the old behaviour (no merging).
-$wgDiff3 = "/usr/bin/diff3";
+$wgDiff3 = '/usr/bin/diff3';
# We can also compress text in the old revisions table. If this is set on,
# old revisions will be compressed on page save if zlib support is available.
@@ -267,18 +270,18 @@ $wgCompressRevisions = false;
# This is the list of preferred extensions for uploading files. Uploading
# files with extensions not in this list will trigger a warning.
-$wgFileExtensions = array( "png", "jpg", "jpeg", "ogg" );
+$wgFileExtensions = array( 'png', 'jpg', 'jpeg', 'ogg' );
# Files with these extensions will never be allowed as uploads.
$wgFileBlacklist = array(
# HTML may contain cookie-stealing JavaScript and web bugs
- "html", "htm",
+ 'html', 'htm',
# PHP scripts may execute arbitrary code on the server
- "php", "phtml", "php3", "php4", "phps",
+ 'php', 'phtml', 'php3', 'php4', 'phps',
# Other types that may be interpreted by some servers
- "shtml", "jhtml", "pl", "py",
+ 'shtml', 'jhtml', 'pl', 'py',
# May contain harmful executables for Windows victims
- "exe", "scr", "dll", "msi", "vbs", "bat", "com", "pif", "cmd", "vxd", "cpl" );
+ 'exe', 'scr', 'dll', 'msi', 'vbs', 'bat', 'com', 'pif', 'cmd', 'vxd', 'cpl' );
# This is a flag to determine whether or not to check file extensions on
# upload.
@@ -288,6 +291,9 @@ $wgCheckFileExtensions = true;
# covered by $wgFileExtensions.
$wgStrictFileExtensions = true;
+# Warn if uploaded files are larger than this
+$wgUploadSizeWarning = 150000;
+
$wgPasswordSalt = true; # For compatibility with old installations set to false
# Which namespaces should support subpages?
@@ -318,7 +324,7 @@ $wgUseImageResize = false;
## of the builtin functions
#
$wgUseImageMagick = false;
-$wgImageMagickConvertCommand = "/usr/bin/convert";
+$wgImageMagickConvertCommand = '/usr/bin/convert';
# PHPTal is a library for page templates. MediaWiki includes
# a recent PHPTal distribution. It is required to use the
@@ -332,6 +338,9 @@ if( !isset( $wgCommandLineMode ) ) {
# Show seconds in Recent Changes
$wgRCSeconds = false;
+# Log IP addresses in the recentchanges table
+$wgPutIPinRC = false;
+
# RDF metadata toggles
$wgEnableDublinCoreRdf = false;
$wgEnableCreativeCommonsRdf = false;
@@ -343,6 +352,14 @@ $wgRightsUrl = NULL;
$wgRightsText = NULL;
$wgRightsIcon = NULL;
+# Set this to true if you want detailed copyright information forms on Upload.
+$wgUseCopyrightUpload = false;
+
+# Set this to false if you want to disable checking that detailed
+# copyright information values are not empty.
+$wgCheckCopyrightUpload = true;
+
+
# Set this to false to avoid forcing the first letter of links
# to capitals. WARNING: may break links! This makes links
# COMPLETELY case-sensitive. Links appearing with a capital at
@@ -364,6 +381,8 @@ $wgMaxCredits = 0;
# Text matching this regular expression will be recognised as spam
# See http://en.wikipedia.org/wiki/Regular_expression
$wgSpamRegex = false;
+# Similarly if this function returns true
+$wgFilterCallback = false;
# Go button goes straight to the edit screen if the article doesn't exist
$wgGoToEdit = false;
@@ -388,8 +407,12 @@ $wgTidyConf = $IP.'/extensions/tidy/tidy.conf';
$wgTidyOpts = '';
# See list of skins and their symbolic names in language/Language.php
-$wgDefaultSkin = "monobook";
+$wgDefaultSkin = 'monobook';
+
+# Whether or not to allow real name fields. Defaults to true.
+$wgAllowRealName = true;
# Extensions
$wgExtensionFunctions = array();
+
?>
diff --git a/includes/DifferenceEngine.php b/includes/DifferenceEngine.php
index 4ba5b7713d8d..2e3937ee4802 100644
--- a/includes/DifferenceEngine.php
+++ b/includes/DifferenceEngine.php
@@ -18,7 +18,9 @@ class DifferenceEngine {
function showDiffPage()
{
global $wgUser, $wgTitle, $wgOut, $wgLang;
-
+ $fname = "DifferenceEngine::showDiffPage";
+ wfProfileIn( $fname );
+
$t = $wgTitle->getPrefixedText() . " (Diff: {$this->mOldid}, " .
"{$this->mNewid})";
$mtext = wfMsg( "missingarticle", $t );
@@ -27,6 +29,7 @@ class DifferenceEngine {
if ( ! $this->loadText() ) {
$wgOut->setPagetitle( wfMsg( "errorpagetitle" ) );
$wgOut->addHTML( $mtext );
+ wfProfileOut( $fname );
return;
}
$wgOut->suppressQuickbar();
@@ -44,6 +47,7 @@ class DifferenceEngine {
if ( !( $this->mOldPage->userCanRead() && $this->mNewPage->userCanRead() ) ) {
$wgOut->loginToUse();
$wgOut->output();
+ wfProfileOut( $fname );
exit;
}
@@ -80,6 +84,8 @@ class DifferenceEngine {
$oldHeader, $newHeader );
$wgOut->addHTML( "<hr /><h2>{$this->mNewtitle}</h2>\n" );
$wgOut->addWikiText( $this->mNewtext );
+
+ wfProfileOut( $fname );
}
function showDiff( $otext, $ntext, $otitle, $ntitle )
@@ -112,9 +118,10 @@ cellpadding='0' cellspacing='4px' class='diff'><tr>
#
function loadText()
{
- global $wgTitle, $wgOut, $wgLang;
+ global $wgTitle, $wgOut, $wgLang, $wgIsMySQL, $wgIsPg;
$fname = "DifferenceEngine::loadText";
+ $oldtable=$wgIsPg?'"old"':'old';
if ( 0 == $this->mNewid || 0 == $this->mOldid ) {
$wgOut->setArticleFlag( true );
$this->mNewtitle = wfMsg( "currentrev" );
@@ -130,7 +137,7 @@ cellpadding='0' cellspacing='4px' class='diff'><tr>
$this->mNewUser = $s->cur_user_text;
$this->mNewComment = $s->cur_comment;
} else {
- $sql = "SELECT old_namespace,old_title,old_timestamp,old_text,old_flags,old_user_text,old_comment FROM old WHERE " .
+ $sql = "SELECT old_namespace,old_title,old_timestamp,old_text,old_flags,old_user_text,old_comment FROM $oldtable WHERE " .
"old_id={$this->mNewid}";
$res = wfQuery( $sql, DB_READ, $fname );
@@ -146,14 +153,15 @@ cellpadding='0' cellspacing='4px' class='diff'><tr>
$this->mNewComment = $s->old_comment;
}
if ( 0 == $this->mOldid ) {
+ $use_index=$wgIsMySQL?"USE INDEX (name_title_timestamp)":"";
$sql = "SELECT old_namespace,old_title,old_timestamp,old_text,old_flags,old_user_text,old_comment " .
- "FROM old USE INDEX (name_title_timestamp) WHERE " .
+ "FROM $oldtable $use_index WHERE " .
"old_namespace=" . $this->mNewPage->getNamespace() . " AND " .
"old_title='" . wfStrencode( $this->mNewPage->getDBkey() ) .
"' ORDER BY inverse_timestamp LIMIT 1";
$res = wfQuery( $sql, DB_READ, $fname );
} else {
- $sql = "SELECT old_namespace,old_title,old_timestamp,old_text,old_flags,old_user_text,old_comment FROM old WHERE " .
+ $sql = "SELECT old_namespace,old_title,old_timestamp,old_text,old_flags,old_user_text,old_comment FROM $oldtable WHERE " .
"old_id={$this->mOldid}";
$res = wfQuery( $sql, DB_READ, $fname );
}
@@ -1015,7 +1023,7 @@ class _HWLDF_WordAccumulator {
function _flushGroup ($new_tag) {
if ($this->_group !== '') {
if ($this->_tag == 'mark')
- $this->_line .= "<font color=\"red\">$this->_group</font>";
+ $this->_line .= '<span class="diffchange">'.$this->_group.'</span>';
else
$this->_line .= $this->_group;
}
@@ -1116,8 +1124,8 @@ class TableDiffFormatter extends DiffFormatter
$l1 = wfMsg( "lineno", $xbeg );
$l2 = wfMsg( "lineno", $ybeg );
- $r = "<tr><td colspan='2' align='left'><strong>{$l1}</strong></td>\n" .
- "<td colspan='2' align='left'><strong>{$l2}</strong></td></tr>\n";
+ $r = '<tr><td colspan="2" align="left"><strong>'.$l1."</strong></td>\n" .
+ '<td colspan="2" align="left"><strong>'.$l2."</strong></td></tr>\n";
return $r;
}
@@ -1133,27 +1141,27 @@ class TableDiffFormatter extends DiffFormatter
}
function addedLine( $line ) {
- return "<td>+</td><td class='diff-addedline'>" .
- "<small>{$line}</small></td>";
+ return '<td>+</td><td class="diff-addedline">' .
+ $line.'</td>';
}
function deletedLine( $line ) {
- return "<td>-</td><td class='diff-deletedline'>" .
- "<small>{$line}</small></td>";
+ return '<td>-</td><td class="diff-deletedline">' .
+ $line.'</td>';
}
function emptyLine() {
- return "<td colspan='2'>&nbsp;</td>";
+ return '<td colspan="2">&nbsp;</td>';
}
function contextLine( $line ) {
- return "<td> </td><td class='diff-context'><small>{$line}</small></td>";
+ return '<td> </td><td class="diff-context">'.$line.'</td>';
}
function _added($lines) {
global $wgOut;
foreach ($lines as $line) {
- $wgOut->addHTML( "<tr>" . $this->emptyLine() .
+ $wgOut->addHTML( '<tr>' . $this->emptyLine() .
$this->addedLine( $line ) . "</tr>\n" );
}
}
@@ -1161,7 +1169,7 @@ class TableDiffFormatter extends DiffFormatter
function _deleted($lines) {
global $wgOut;
foreach ($lines as $line) {
- $wgOut->addHTML( "<tr>" . $this->deletedLine( $line ) .
+ $wgOut->addHTML( '<tr>' . $this->deletedLine( $line ) .
$this->emptyLine() . "</tr>\n" );
}
}
@@ -1169,7 +1177,7 @@ class TableDiffFormatter extends DiffFormatter
function _context( $lines ) {
global $wgOut;
foreach ($lines as $line) {
- $wgOut->addHTML( "<tr>" . $this->contextLine( $line ) .
+ $wgOut->addHTML( '<tr>' . $this->contextLine( $line ) .
$this->contextLine( $line ) . "</tr>\n" );
}
}
@@ -1182,7 +1190,7 @@ class TableDiffFormatter extends DiffFormatter
while ( $line = array_shift( $del ) ) {
$aline = array_shift( $add );
- $wgOut->addHTML( "<tr>" . $this->deletedLine( $line ) .
+ $wgOut->addHTML( '<tr>' . $this->deletedLine( $line ) .
$this->addedLine( $aline ) . "</tr>\n" );
}
$this->_added( $add ); # If any leftovers
diff --git a/includes/EditPage.php b/includes/EditPage.php
index d9959ae39f97..2d779ac70efb 100644
--- a/includes/EditPage.php
+++ b/includes/EditPage.php
@@ -62,6 +62,7 @@ class EditPage {
}
function importFormData( &$request ) {
+ global $wgIsMySQL, $wgIsPg;
# These fields need to be checked for encoding.
# Also remove trailing whitespace, but don't remove _initial_
# whitespace from the text boxes. This may be significant formatting.
@@ -70,7 +71,12 @@ class EditPage {
$this->summary = trim( $request->getText( "wpSummary" ) );
$this->edittime = $request->getVal( 'wpEdittime' );
- if( !preg_match( '/^\d{14}$/', $this->edittime ) ) $this->edittime = "";
+ if ($wgIsMySQL)
+ if( !preg_match( '/^\d{14}$/', $this->edittime )) $this->edittime = "";
+ if ($wgIsPg)
+ if ( !preg_match( '/^\d{4}-\d\d-\d\d \d\d:\d\d:\d\d$/',
+ $this->edittime ))
+ $this->edittime = "";
$this->preview = $request->getCheck( 'wpPreview' );
$this->save = $request->wasPosted() && !$this->preview;
@@ -108,7 +114,7 @@ class EditPage {
global $wgLang, $wgParser, $wgTitle;
global $wgAllowAnonymousMinor;
global $wgWhitelistEdit;
- global $wgSpamRegex;
+ global $wgSpamRegex, $wgFilterCallback;
$sk = $wgUser->getSkin();
$isConflict = false;
@@ -131,9 +137,12 @@ class EditPage {
if ( "save" == $formtype ) {
# Check for spam
if ( $wgSpamRegex && preg_match( $wgSpamRegex, $this->textbox1 ) ) {
- sleep(10);
- $wgOut->redirect( $this->mTitle->getFullURL() );
- return;
+ $this->spamPage();
+ return;
+ }
+ if ( $wgFilterCallback && $wgFilterCallback( $this->mTitle, $this->textbox1, $this->section ) ) {
+ # Error messages or other handling should be performed by the filter function
+ return;
}
if ( $wgUser->isBlocked() ) {
$this->blockedIPpage();
@@ -200,13 +209,19 @@ class EditPage {
$hasmatch = preg_match( "/^ *([=]{1,6})(.*?)(\\1) *\\n/i", $this->textbox1, $matches );
# we can't deal with anchors, includes, html etc in the header for now,
# headline would need to be parsed to improve this
- if($hasmatch and strlen($matches[2]) > 0 and !preg_match( "/[\\['{<>]/", $matches[2])) {
+ #if($hasmatch and strlen($matches[2]) > 0 and !preg_match( "/[\\['{<>]/", $matches[2])) {
+ if($hasmatch and strlen($matches[2]) > 0) {
global $wgInputEncoding;
$headline = do_html_entity_decode( $matches[2], ENT_COMPAT, $wgInputEncoding );
- # strip out HTML, will be useful when
- # $headline = preg_replace( "/<.*?" . ">/","",$headline );
+ # strip out HTML
+ $headline = preg_replace( "/<.*?" . ">/","",$headline );
$headline = trim( $headline );
- $sectionanchor = '#'.preg_replace("/[ \\?&\\/<>\\(\\)\\[\\]=,+']+/", '_', urlencode( $headline ) );
+ $sectionanchor = '#'.urlencode( str_replace(' ', '_', $headline ) );
+ $replacearray = array(
+ '%3A' => ':',
+ '%' => '.'
+ );
+ $sectionanchor = str_replace(array_keys($replacearray),array_values($replacearray),$sectionanchor);
}
}
@@ -301,12 +316,12 @@ class EditPage {
$save = wfMsg( "savearticle" );
$prev = wfMsg( "showpreview" );
- $cancel = $sk->makeKnownLink( $this->mTitle->getPrefixedURL(),
+ $cancel = $sk->makeKnownLink( $this->mTitle->getPrefixedText(),
wfMsg( "cancel" ) );
- $edithelpurl = $sk->makeUrl( wfMsg( "edithelppage" ));
- $edithelp = '<a onclick="window.open('.
- "'$edithelpurl', 'helpwindow', 'width=610,height=400,left=10,top=10'".'); return false;" href="'.$edithelpurl.'">'.
- wfMsg( "edithelp" ).'</a>';
+ $edithelpurl = $sk->makeUrl( wfMsg( 'edithelppage' ));
+ $edithelp = '<a target="helpwindow" href="'.$edithelpurl.'">'.
+ htmlspecialchars( wfMsg( 'edithelp' ) ).'</a> '.
+ htmlspecialchars( wfMsg( 'newwindow' ) );
$copywarn = wfMsg( "copyrightwarning", $sk->makeKnownLink(
wfMsg( "copyrightpage" ) ) );
@@ -354,7 +369,6 @@ class EditPage {
$previewhead.="<h2>" . wfMsg( "previewconflict" ) .
"</h2>\n";
}
- $previewtext = wfUnescapeHTML( $this->textbox1 );
$parserOptions = ParserOptions::newFromUser( $wgUser );
$parserOptions->setUseCategoryMagic( false );
@@ -371,7 +385,7 @@ class EditPage {
$parserOutput = $wgParser->parse( $previewtext , $wgTitle, $parserOptions );
$wgOut->addHTML( $parserOutput->mText );
} else {
- $parserOutput = $wgParser->parse( $this->mArticle->preSaveTransform( $previewtext ) ."\n\n",
+ $parserOutput = $wgParser->parse( $this->mArticle->preSaveTransform( $this->textbox1 ) ."\n\n",
$wgTitle, $parserOptions );
$previewHTML = $parserOutput->mText;
@@ -379,6 +393,8 @@ class EditPage {
$wgOut->addHTML($previewhead);
$wgOut->addHTML($previewHTML);
}
+ $wgOut->addCategoryLinks($parserOutput->getCategoryLinks());
+ $wgOut->addLanguageLinks($parserOutput->getLanguageLinks());
$wgOut->addHTML( "<br style=\"clear:both;\" />\n" );
}
}
@@ -410,12 +426,12 @@ htmlspecialchars( $wgLang->recodeForEdit( $this->textbox1 ) ) .
</textarea>
<br />{$editsummary}
{$checkboxhtml}
-<input tabindex='5' type='submit' value=\"{$save}\" name=\"wpSave\" accesskey=\"".wfMsg('accesskey-save')."\"".
+<input tabindex='5' id='wpSave' type='submit' value=\"{$save}\" name=\"wpSave\" accesskey=\"".wfMsg('accesskey-save')."\"".
" title=\"".wfMsg('tooltip-save')."\"/>
-<input tabindex='6' type='submit' value=\"{$prev}\" name=\"wpPreview\" accesskey=\"".wfMsg('accesskey-preview')."\"".
+<input tabindex='6' id='wpSave' type='submit' value=\"{$prev}\" name=\"wpPreview\" accesskey=\"".wfMsg('accesskey-preview')."\"".
" title=\"".wfMsg('tooltip-preview')."\"/>
<em>{$cancel}</em> | <em>{$edithelp}</em>
-<br /><br />{$copywarn}
+<br /><div id=\"editpage-copywarn\">{$copywarn}</div>
<input type='hidden' value=\"" . htmlspecialchars( $this->section ) . "\" name=\"wpSection\" />
<input type='hidden' value=\"{$this->edittime}\" name=\"wpEdittime\" />\n" );
@@ -425,7 +441,7 @@ htmlspecialchars( $wgLang->recodeForEdit( $this->textbox1 ) ) .
wfMsg( "yourtext" ), wfMsg( "storedversion" ) );
$wgOut->addHTML( "<h2>" . wfMsg( "yourtext" ) . "</h2>
-<textarea tabindex=6 name=\"wpTextbox2\" rows='{$rows}' cols='{$cols}' wrap='virtual'>"
+<textarea tabindex=6 id='wpTextbox2' name=\"wpTextbox2\" rows='{$rows}' cols='{$cols}' wrap='virtual'>"
. htmlspecialchars( $wgLang->recodeForEdit( $this->textbox2 ) ) .
"
</textarea>" );
@@ -450,7 +466,11 @@ htmlspecialchars( $wgLang->recodeForEdit( $this->textbox1 ) ) .
$reason = $wgUser->blockedFor();
$ip = $wgIP;
- $name = User::whoIs( $id );
+ if ( is_string( $id ) ) {
+ $name = $id;
+ } else {
+ $name = User::whoIs( $id );
+ }
$link = "[[" . $wgLang->getNsText( Namespace::getUser() ) .
":{$name}|{$name}]]";
@@ -472,6 +492,17 @@ htmlspecialchars( $wgLang->recodeForEdit( $this->textbox1 ) ) .
$wgOut->returnToMain( false );
}
+ function spamPage()
+ {
+ global $wgOut;
+ $wgOut->setPageTitle( wfMsg( "spamprotectiontitle" ) );
+ $wgOut->setRobotpolicy( "noindex,nofollow" );
+ $wgOut->setArticleRelated( false );
+
+ $wgOut->addWikiText( wfMsg( "spamprotectiontext" ) );
+ $wgOut->returnToMain( false );
+ }
+
# Forks processes to scan the originating IP for an open proxy server
# MemCached can be used to skip IPs that have already been scanned
function proxyCheck()
@@ -516,6 +547,7 @@ htmlspecialchars( $wgLang->recodeForEdit( $this->textbox1 ) ) .
}
/* private */ function mergeChangesInto( &$text ){
+ global $wgIsPg;
$oldDate = $this->edittime;
$res = wfQuery("SELECT cur_text FROM cur WHERE cur_id=" .
$this->mTitle->getArticleID() . " FOR UPDATE", DB_WRITE);
@@ -524,10 +556,13 @@ htmlspecialchars( $wgLang->recodeForEdit( $this->textbox1 ) ) .
$yourtext = $obj->cur_text;
$ns = $this->mTitle->getNamespace();
$title = wfStrencode( $this->mTitle->getDBkey() );
- $res = wfQuery("SELECT old_text FROM old WHERE old_namespace = $ns AND ".
+ $oldtable=$wgIsPg?'"old"':'old';
+ $res = wfQuery("SELECT old_text,old_flags FROM $oldtable WHERE old_namespace = $ns AND ".
"old_title = '{$title}' AND old_timestamp = '{$oldDate}'", DB_WRITE);
$obj = wfFetchObject($res);
- if(wfMerge($obj->old_text, $text, $yourtext, $result)){
+ $oldText = Article::getRevisionText( $obj );
+
+ if(wfMerge($oldText, $text, $yourtext, $result)){
$text = $result;
return true;
} else {
diff --git a/includes/Feed.php b/includes/Feed.php
index 0be93e8a7017..b0d208b251e1 100644
--- a/includes/Feed.php
+++ b/includes/Feed.php
@@ -20,18 +20,18 @@
# http://www.gnu.org/copyleft/gpl.html
$wgFeedClasses = array(
- "rss" => "RSSFeed",
- "atom" => "AtomFeed",
+ 'rss' => 'RSSFeed',
+ 'atom' => 'AtomFeed',
);
class FeedItem {
- var $Title = "Wiki";
- var $Description = "";
- var $Url = "";
- var $Date = "";
- var $Author = "";
+ var $Title = 'Wiki';
+ var $Description = '';
+ var $Url = '';
+ var $Date = '';
+ var $Author = '';
- function FeedItem( $Title, $Description, $Url, $Date = "", $Author = "", $Comments = "" ) {
+ function FeedItem( $Title, $Description, $Url, $Date = '', $Author = '', $Comments = '' ) {
$this->Title = $Title;
$this->Description = $Description;
$this->Url = $Url;
@@ -44,8 +44,8 @@ class FeedItem {
function xmlEncode( $string ) {
global $wgInputEncoding, $wgLang;
$string = str_replace( "\r\n", "\n", $string );
- if( strcasecmp( $wgInputEncoding, "utf-8" ) != 0 ) {
- $string = $wgLang->iconv( $wgInputEncoding, "utf-8", $string );
+ if( strcasecmp( $wgInputEncoding, 'utf-8' ) != 0 ) {
+ $string = $wgLang->iconv( $wgInputEncoding, 'utf-8', $string );
}
return htmlspecialchars( $string );
}
@@ -85,7 +85,7 @@ class ChannelFeed extends FeedItem {
# print "</feed>";
}
- function outXmlHeader( $mimetype="application/xml" ) {
+ function outXmlHeader( $mimetype='application/xml' ) {
global $wgServer, $wgStylePath, $wgOut;
# We take over from $wgOut, excepting its cache header info
@@ -102,7 +102,7 @@ class ChannelFeed extends FeedItem {
class RSSFeed extends ChannelFeed {
function formatTime( $ts ) {
- return gmdate( "D, d M Y H:i:s \G\M\T", wfTimestamp2Unix( $ts ) );
+ return gmdate( 'D, d M Y H:i:s \G\M\T', wfTimestamp2Unix( $ts ) );
}
function outHeader() {
@@ -143,7 +143,7 @@ class RSSFeed extends ChannelFeed {
class AtomFeed extends ChannelFeed {
function formatTime( $ts ) {
// need to use RFC 822 time format at least for rss2.0
- return gmdate( "Y-m-d\TH:i:s", wfTimestamp2Unix( $ts ) );
+ return gmdate( 'Y-m-d\TH:i:s', wfTimestamp2Unix( $ts ) );
}
function outHeader() {
@@ -186,4 +186,4 @@ class AtomFeed extends ChannelFeed {
}
}
-?> \ No newline at end of file
+?>
diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php
index 8989b6078d75..dd5197d07d11 100644
--- a/includes/GlobalFunctions.php
+++ b/includes/GlobalFunctions.php
@@ -5,9 +5,9 @@ $wgNumberOfArticles = -1; # Unset
$wgTotalViews = -1;
$wgTotalEdits = -1;
-require_once( "DatabaseFunctions.php" );
-require_once( "UpdateClasses.php" );
-require_once( "LogPage.php" );
+require_once( 'DatabaseFunctions.php' );
+require_once( 'UpdateClasses.php' );
+require_once( 'LogPage.php' );
/*
* Compatibility functions
@@ -23,8 +23,8 @@ if( !function_exists('iconv') ) {
# This will *not* work in all circumstances.
function iconv( $from, $to, $string ) {
if(strcasecmp( $from, $to ) == 0) return $string;
- if(strcasecmp( $from, "utf-8" ) == 0) return utf8_decode( $string );
- if(strcasecmp( $to, "utf-8" ) == 0) return utf8_encode( $string );
+ if(strcasecmp( $from, 'utf-8' ) == 0) return utf8_decode( $string );
+ if(strcasecmp( $to, 'utf-8' ) == 0) return utf8_encode( $string );
return $string;
}
}
@@ -32,7 +32,7 @@ if( !function_exists('iconv') ) {
if( !function_exists('file_get_contents') ) {
# Exists in PHP 4.3.0+
function file_get_contents( $filename ) {
- return implode( "", file( $filename ) );
+ return implode( '', file( $filename ) );
}
}
@@ -40,22 +40,22 @@ if( !function_exists('is_a') ) {
# Exists in PHP 4.2.0+
function is_a( $object, $class_name ) {
return
- (strcasecmp( get_class( $object, $class_name ) == 0) ||
- is_subclass_of( $object, $class_name ) );
+ (strcasecmp( get_class( $object ), $class_name ) == 0) ||
+ is_subclass_of( $object, $class_name );
}
}
# html_entity_decode exists in PHP 4.3.0+ but is FATALLY BROKEN even then,
# with no UTF-8 support.
-function do_html_entity_decode( $string, $quote_style=ENT_COMPAT, $charset="ISO-8859-1" ) {
+function do_html_entity_decode( $string, $quote_style=ENT_COMPAT, $charset='ISO-8859-1' ) {
static $trans;
if( !isset( $trans ) ) {
$trans = array_flip( get_html_translation_table( HTML_ENTITIES, $quote_style ) );
# Assumes $charset will always be the same through a run, and only understands
# utf-8 or default. Note - mixing latin1 named entities and unicode numbered
# ones will result in a bad link.
- if( strcasecmp( "utf-8", $charset ) == 0 ) {
- $trans = array_map( "utf8_encode", $trans );
+ if( strcasecmp( 'utf-8', $charset ) == 0 ) {
+ $trans = array_map( 'utf8_encode', $trans );
}
}
return strtr( $string, $trans );
@@ -77,19 +77,19 @@ function wfSeedRandom()
# Generates a URL from a URL-encoded title and a query string
# Title::getLocalURL() is preferred in most cases
#
-function wfLocalUrl( $a, $q = "" )
+function wfLocalUrl( $a, $q = '' )
{
global $wgServer, $wgScript, $wgArticlePath;
- $a = str_replace( " ", "_", $a );
+ $a = str_replace( ' ', '_', $a );
- if ( "" == $a ) {
- if( "" == $q ) {
+ if ( '' == $a ) {
+ if( '' == $q ) {
$a = $wgScript;
} else {
$a = "{$wgScript}?{$q}";
}
- } else if ( "" == $q ) {
+ } else if ( '' == $q ) {
$a = str_replace( "$1", $a, $wgArticlePath );
} else if ($wgScript != '' ) {
$a = "{$wgScript}?title={$a}&{$q}";
@@ -99,18 +99,18 @@ function wfLocalUrl( $a, $q = "" )
return $a;
}
-function wfLocalUrlE( $a, $q = "" )
+function wfLocalUrlE( $a, $q = '' )
{
return wfEscapeHTML( wfLocalUrl( $a, $q ) );
# die( "Call to obsolete function wfLocalUrlE()" );
}
-function wfFullUrl( $a, $q = "" ) {
- wfDebugDieBacktrace( "Call to obsolete function wfFullUrl(); use Title::getFullURL" );
+function wfFullUrl( $a, $q = '' ) {
+ wfDebugDieBacktrace( 'Call to obsolete function wfFullUrl(); use Title::getFullURL' );
}
-function wfFullUrlE( $a, $q = "" ) {
- wfDebugDieBacktrace( "Call to obsolete function wfFullUrlE(); use Title::getFullUrlE" );
+function wfFullUrlE( $a, $q = '' ) {
+ wfDebugDieBacktrace( 'Call to obsolete function wfFullUrlE(); use Title::getFullUrlE' );
}
@@ -143,27 +143,28 @@ function wfImageArchiveUrl( $name )
function wfUrlencode ( $s )
{
$s = urlencode( $s );
- $s = preg_replace( "/%3[Aa]/", ":", $s );
- $s = preg_replace( "/%2[Ff]/", "/", $s );
+ $s = preg_replace( '/%3[Aa]/', ':', $s );
+ $s = preg_replace( '/%2[Ff]/', '/', $s );
return $s;
}
function wfUtf8Sequence($codepoint) {
- if($codepoint < 0x80) return chr($codepoint);
- if($codepoint < 0x800) return chr($codepoint >> 6 & 0x3f | 0xc0) .
- chr($codepoint & 0x3f | 0x80);
- if($codepoint < 0x10000) return chr($codepoint >> 12 & 0x0f | 0xe0) .
- chr($codepoint >> 6 & 0x3f | 0x80) .
- chr($codepoint & 0x3f | 0x80);
+ if($codepoint < 0x80) return chr($codepoint);
+ if($codepoint < 0x800) return chr($codepoint >> 6 & 0x3f | 0xc0) .
+ chr($codepoint & 0x3f | 0x80);
+ if($codepoint < 0x10000) return chr($codepoint >> 12 & 0x0f | 0xe0) .
+ chr($codepoint >> 6 & 0x3f | 0x80) .
+ chr($codepoint & 0x3f | 0x80);
if($codepoint < 0x100000) return chr($codepoint >> 18 & 0x07 | 0xf0) . # Double-check this
- chr($codepoint >> 12 & 0x3f | 0x80) .
- chr($codepoint >> 6 & 0x3f | 0x80) .
- chr($codepoint & 0x3f | 0x80);
+ chr($codepoint >> 12 & 0x3f | 0x80) .
+ chr($codepoint >> 6 & 0x3f | 0x80) .
+ chr($codepoint & 0x3f | 0x80);
# Doesn't yet handle outside the BMP
return "&#$codepoint;";
}
+# Converts numeric character entities to UTF-8
function wfMungeToUtf8($string) {
global $wgInputEncoding; # This is debatable
#$string = iconv($wgInputEncoding, "UTF-8", $string);
@@ -189,7 +190,7 @@ function wfUtf8Entity( $matches ) {
}
if ( $length != strlen( $char ) ) {
- return "";
+ return '';
}
if ( $length == 1 ) {
return $char;
@@ -235,23 +236,25 @@ function logProfilingData()
list( $usec, $sec ) = explode( " ", $wgRequestTime );
$start = (float)$sec + (float)$usec;
$elapsed = $now - $start;
- if ( "" != $wgDebugLogFile ) {
+ if ( $wgProfiling ) {
$prof = wfGetProfilingOutput( $start, $elapsed );
- $forward = "";
+ $forward = '';
if( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
- $forward = " forwarded for " . $_SERVER['HTTP_X_FORWARDED_FOR'];
+ $forward = ' forwarded for ' . $_SERVER['HTTP_X_FORWARDED_FOR'];
if( !empty( $_SERVER['HTTP_CLIENT_IP'] ) )
- $forward .= " client IP " . $_SERVER['HTTP_CLIENT_IP'];
+ $forward .= ' client IP ' . $_SERVER['HTTP_CLIENT_IP'];
if( !empty( $_SERVER['HTTP_FROM'] ) )
- $forward .= " from " . $_SERVER['HTTP_FROM'];
+ $forward .= ' from ' . $_SERVER['HTTP_FROM'];
if( $forward )
$forward = "\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})";
if($wgUser->getId() == 0)
- $forward .= " anon";
+ $forward .= ' anon';
$log = sprintf( "%s\t%04.3f\t%s\n",
- gmdate( "YmdHis" ), $elapsed,
+ gmdate( 'YmdHis' ), $elapsed,
urldecode( $_SERVER['REQUEST_URI'] . $forward ) );
- error_log( $log . $prof, 3, $wgDebugLogFile );
+ if ( '' != $wgDebugLogFile ) {
+ error_log( $log . $prof, 3, $wgDebugLogFile );
+ }
}
}
@@ -288,7 +291,7 @@ function wfMsgNoDB( $key ) {
function wfMsgReal( $key, $args, $useDB ) {
global $wgReplacementKeys, $wgMessageCache, $wgLang;
- $fname = "wfMsg";
+ $fname = 'wfMsg';
wfProfileIn( $fname );
if ( $wgMessageCache ) {
$message = $wgMessageCache->get( $key, $useDB );
@@ -309,28 +312,28 @@ function wfMsgReal( $key, $args, $useDB ) {
function wfCleanFormFields( $fields )
{
- wfDebugDieBacktrace( "Call to obsolete wfCleanFormFields(). Use wgRequest instead..." );
+ wfDebugDieBacktrace( 'Call to obsolete wfCleanFormFields(). Use wgRequest instead...' );
}
function wfMungeQuotes( $in )
{
- $out = str_replace( "%", "%25", $in );
- $out = str_replace( "'", "%27", $out );
- $out = str_replace( "\"", "%22", $out );
+ $out = str_replace( '%', '%25', $in );
+ $out = str_replace( "'", '%27', $out );
+ $out = str_replace( '"', '%22', $out );
return $out;
}
function wfDemungeQuotes( $in )
{
- $out = str_replace( "%22", "\"", $in );
- $out = str_replace( "%27", "'", $out );
- $out = str_replace( "%25", "%", $out );
+ $out = str_replace( '%22', '"', $in );
+ $out = str_replace( '%27', "'", $out );
+ $out = str_replace( '%25', '%', $out );
return $out;
}
function wfCleanQueryVar( $var )
{
- wfDebugDieBacktrace( "Call to obsolete function wfCleanQueryVar(); use wgRequest instead" );
+ wfDebugDieBacktrace( 'Call to obsolete function wfCleanQueryVar(); use wgRequest instead' );
}
function wfSearch( $s )
@@ -353,30 +356,48 @@ function wfAbruptExit(){
}
$called = true;
- if( function_exists( "debug_backtrace" ) ){ // PHP >= 4.3
+ if( function_exists( 'debug_backtrace' ) ){ // PHP >= 4.3
$bt = debug_backtrace();
for($i = 0; $i < count($bt) ; $i++){
- $file = $bt[$i]["file"];
- $line = $bt[$i]["line"];
+ $file = $bt[$i]['file'];
+ $line = $bt[$i]['line'];
wfDebug("WARNING: Abrupt exit in $file at line $line\n");
}
} else {
- wfDebug("WARNING: Abrupt exit\n");
+ wfDebug('WARNING: Abrupt exit\n');
}
exit();
}
-function wfDebugDieBacktrace( $msg = "" ) {
- $msg .= "\n<p>Backtrace:</p>\n<ul>\n";
- $backtrace = debug_backtrace();
- foreach( $backtrace as $call ) {
- $f = explode( DIRECTORY_SEPARATOR, $call['file'] );
- $file = $f[count($f)-1];
- $msg .= "<li>" . $file . " line " . $call['line'] . ", in ";
- if( !empty( $call['class'] ) ) $msg .= $call['class'] . "::";
- $msg .= $call['function'] . "()</li>\n";
- }
- die( $msg );
+function wfDebugDieBacktrace( $msg = '' ) {
+ global $wgCommandLineMode;
+
+ if ( function_exists( 'debug_backtrace' ) ) {
+ if ( $wgCommandLineMode ) {
+ $msg .= "\nBacktrace:\n";
+ } else {
+ $msg .= "\n<p>Backtrace:</p>\n<ul>\n";
+ }
+ $backtrace = debug_backtrace();
+ foreach( $backtrace as $call ) {
+ $f = explode( DIRECTORY_SEPARATOR, $call['file'] );
+ $file = $f[count($f)-1];
+ if ( $wgCommandLineMode ) {
+ $msg .= "$file line {$call['line']}, in ";
+ } else {
+ $msg .= '<li>' . $file . " line " . $call['line'] . ', in ';
+ }
+ if( !empty( $call['class'] ) ) $msg .= $call['class'] . '::';
+ $msg .= $call['function'] . "()";
+
+ if ( $wgCommandLineMode ) {
+ $msg .= "\n";
+ } else {
+ $msg .= "</li>\n";
+ }
+ }
+ }
+ die( $msg );
}
function wfNumberOfArticles()
@@ -392,9 +413,9 @@ function wfNumberOfArticles()
global $wgNumberOfArticles, $wgTotalViews, $wgTotalEdits;
if ( -1 != $wgNumberOfArticles ) return;
- $sql = "SELECT ss_total_views, ss_total_edits, ss_good_articles " .
- "FROM site_stats WHERE ss_row_id=1";
- $res = wfQuery( $sql, DB_READ, "wfLoadSiteStats" );
+ $sql = 'SELECT ss_total_views, ss_total_edits, ss_good_articles ' .
+ 'FROM site_stats WHERE ss_row_id=1';
+ $res = wfQuery( $sql, DB_READ, 'wfLoadSiteStats' );
if ( 0 == wfNumRows( $res ) ) { return; }
else {
@@ -408,24 +429,24 @@ function wfNumberOfArticles()
function wfEscapeHTML( $in )
{
return str_replace(
- array( "&", "\"", ">", "<" ),
- array( "&amp;", "&quot;", "&gt;", "&lt;" ),
+ array( '&', '"', '>', '<' ),
+ array( '&amp;', '&quot;', '&gt;', '&lt;' ),
$in );
}
function wfEscapeHTMLTagsOnly( $in ) {
return str_replace(
- array( "\"", ">", "<" ),
- array( "&quot;", "&gt;", "&lt;" ),
+ array( '"', '>', '<' ),
+ array( '&quot;', '&gt;', '&lt;' ),
$in );
}
function wfUnescapeHTML( $in )
{
- $in = str_replace( "&lt;", "<", $in );
- $in = str_replace( "&gt;", ">", $in );
- $in = str_replace( "&quot;", "\"", $in );
- $in = str_replace( "&amp;", "&", $in );
+ $in = str_replace( '&lt;', '<', $in );
+ $in = str_replace( '&gt;', '>', $in );
+ $in = str_replace( '&quot;', '"', $in );
+ $in = str_replace( '&amp;', '&', $in );
return $in;
}
@@ -435,21 +456,21 @@ function wfImageDir( $fname )
$hash = md5( $fname );
$oldumask = umask(0);
- $dest = $wgUploadDirectory . "/" . $hash{0};
+ $dest = $wgUploadDirectory . '/' . $hash{0};
if ( ! is_dir( $dest ) ) { mkdir( $dest, 0777 ); }
- $dest .= "/" . substr( $hash, 0, 2 );
+ $dest .= '/' . substr( $hash, 0, 2 );
if ( ! is_dir( $dest ) ) { mkdir( $dest, 0777 ); }
umask( $oldumask );
return $dest;
}
-function wfImageThumbDir( $fname , $subdir="thumb")
+function wfImageThumbDir( $fname , $subdir='thumb')
{
return wfImageArchiveDir( $fname, $subdir );
}
-function wfImageArchiveDir( $fname , $subdir="archive")
+function wfImageArchiveDir( $fname , $subdir='archive')
{
global $wgUploadDirectory;
@@ -460,9 +481,9 @@ function wfImageArchiveDir( $fname , $subdir="archive")
# be written we'll worry about it then.
$archive = "{$wgUploadDirectory}/{$subdir}";
if ( ! is_dir( $archive ) ) { @mkdir( $archive, 0777 ); }
- $archive .= "/" . $hash{0};
+ $archive .= '/' . $hash{0};
if ( ! is_dir( $archive ) ) { @mkdir( $archive, 0777 ); }
- $archive .= "/" . substr( $hash, 0, 2 );
+ $archive .= '/' . substr( $hash, 0, 2 );
if ( ! is_dir( $archive ) ) { @mkdir( $archive, 0777 ); }
umask( $oldumask );
@@ -474,9 +495,9 @@ function wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus = "", $source
global $wgUser, $wgLang, $wgTitle, $wgOut, $wgDeferredUpdateList;
global $wgUseCopyrightUpload;
- $fname = "wfRecordUpload";
+ $fname = 'wfRecordUpload';
- $sql = "SELECT img_name,img_size,img_timestamp,img_description,img_user," .
+ $sql = 'SELECT img_name,img_size,img_timestamp,img_description,img_user,' .
"img_user_text FROM image WHERE img_name='" . wfStrencode( $name ) . "'";
$res = wfQuery( $sql, DB_READ, $fname );
@@ -486,9 +507,9 @@ function wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus = "", $source
if ( $wgUseCopyrightUpload )
{
- $textdesc = "== " . wfMsg ( "filedesc" ) . " ==\n" . $desc . "\n" .
- "== " . wfMsg ( "filestatus" ) . " ==\n" . $copyStatus . "\n" .
- "== " . wfMsg ( "filesource" ) . " ==\n" . $source ;
+ $textdesc = '== ' . wfMsg ( 'filedesc' ) . " ==\n" . $desc . "\n" .
+ '== ' . wfMsg ( 'filestatus' ) . " ==\n" . $copyStatus . "\n" .
+ '== ' . wfMsg ( 'filesource' ) . " ==\n" . $source ;
}
else $textdesc = $desc ;
@@ -496,27 +517,27 @@ function wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus = "", $source
$won = wfInvertTimestamp( $now );
if ( 0 == wfNumRows( $res ) ) {
- $sql = "INSERT INTO image (img_name,img_size,img_timestamp," .
+ $sql = 'INSERT INTO image (img_name,img_size,img_timestamp,' .
"img_description,img_user,img_user_text) VALUES ('" .
wfStrencode( $name ) . "',$size,'{$now}','" .
wfStrencode( $desc ) . "', '" . $wgUser->getID() .
"', '" . wfStrencode( $wgUser->getName() ) . "')";
wfQuery( $sql, DB_WRITE, $fname );
- $sql = "SELECT cur_id,cur_text FROM cur WHERE cur_namespace=" .
+ $sql = 'SELECT cur_id,cur_text FROM cur WHERE cur_namespace=' .
Namespace::getImage() . " AND cur_title='" .
wfStrencode( $name ) . "'";
$res = wfQuery( $sql, DB_READ, $fname );
if ( 0 == wfNumRows( $res ) ) {
- $common =
+ $common =
Namespace::getImage() . ",'" .
wfStrencode( $name ) . "','" .
wfStrencode( $desc ) . "','" . $wgUser->getID() . "','" .
wfStrencode( $wgUser->getName() ) . "','" . $now .
"',1";
- $sql = "INSERT INTO cur (cur_namespace,cur_title," .
- "cur_comment,cur_user,cur_user_text,cur_timestamp,cur_is_new," .
- "cur_text,inverse_timestamp,cur_touched) VALUES (" .
+ $sql = 'INSERT INTO cur (cur_namespace,cur_title,' .
+ 'cur_comment,cur_user,cur_user_text,cur_timestamp,cur_is_new,' .
+ 'cur_text,inverse_timestamp,cur_touched) VALUES (' .
$common .
",'" . wfStrencode( $textdesc ) . "','{$won}','{$now}')";
wfQuery( $sql, DB_WRITE, $fname );
@@ -531,7 +552,7 @@ function wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus = "", $source
} else {
$s = wfFetchObject( $res );
- $sql = "INSERT INTO oldimage (oi_name,oi_archive_name,oi_size," .
+ $sql = 'INSERT INTO oldimage (oi_name,oi_archive_name,oi_size,' .
"oi_timestamp,oi_description,oi_user,oi_user_text) VALUES ('" .
wfStrencode( $s->img_name ) . "','" .
wfStrencode( $oldver ) .
@@ -555,10 +576,10 @@ function wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus = "", $source
wfQuery( $sql, DB_WRITE, $fname );
}
- $log = new LogPage( wfMsg( "uploadlogpage" ), wfMsg( "uploadlogpagetext" ) );
- $da = wfMsg( "uploadedimage", "[[:" . $wgLang->getNsText(
+ $log = new LogPage( wfMsg( 'uploadlogpage' ), wfMsg( 'uploadlogpagetext' ) );
+ $da = wfMsg( 'uploadedimage', '[[:' . $wgLang->getNsText(
Namespace::getImage() ) . ":{$name}|{$name}]]" );
- $ta = wfMsg( "uploadedimage", $name );
+ $ta = wfMsg( 'uploadedimage', $name );
$log->addEntry( $da, $desc, $ta );
}
@@ -568,21 +589,21 @@ function wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus = "", $source
function wfShowingResults( $offset, $limit )
{
global $wgLang;
- return wfMsg( "showingresults", $wgLang->formatNum( $limit ), $wgLang->formatNum( $offset+1 ) );
+ return wfMsg( 'showingresults', $wgLang->formatNum( $limit ), $wgLang->formatNum( $offset+1 ) );
}
function wfShowingResultsNum( $offset, $limit, $num )
{
global $wgLang;
- return wfMsg( "showingresultsnum", $wgLang->formatNum( $limit ), $wgLang->formatNum( $offset+1 ), $wgLang->formatNum( $num ) );
+ return wfMsg( 'showingresultsnum', $wgLang->formatNum( $limit ), $wgLang->formatNum( $offset+1 ), $wgLang->formatNum( $num ) );
}
-function wfViewPrevNext( $offset, $limit, $link, $query = "", $atend = false )
+function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false )
{
global $wgUser, $wgLang;
$fmtLimit = $wgLang->formatNum( $limit );
- $prev = wfMsg( "prevn", $fmtLimit );
- $next = wfMsg( "nextn", $fmtLimit );
+ $prev = wfMsg( 'prevn', $fmtLimit );
+ $next = wfMsg( 'nextn', $fmtLimit );
$link = wfUrlencode( $link );
$sk = $wgUser->getSkin();
@@ -590,8 +611,8 @@ function wfViewPrevNext( $offset, $limit, $link, $query = "", $atend = false )
$po = $offset - $limit;
if ( $po < 0 ) { $po = 0; }
$q = "limit={$limit}&offset={$po}";
- if ( "" != $query ) { $q .= "&{$query}"; }
- $plink = "<a href=\"" . wfLocalUrlE( $link, $q ) . "\">{$prev}</a>";
+ if ( '' != $query ) { $q .= "&{$query}"; }
+ $plink = '<a href="' . wfLocalUrlE( $link, $q ) . "\">{$prev}</a>";
} else { $plink = $prev; }
$no = $offset + $limit;
@@ -601,26 +622,26 @@ function wfViewPrevNext( $offset, $limit, $link, $query = "", $atend = false )
if ( $atend ) {
$nlink = $next;
} else {
- $nlink = "<a href=\"" . wfLocalUrlE( $link, $q ) . "\">{$next}</a>";
+ $nlink = '<a href="' . wfLocalUrlE( $link, $q ) . "\">{$next}</a>";
}
- $nums = wfNumLink( $offset, 20, $link , $query ) . " | " .
- wfNumLink( $offset, 50, $link, $query ) . " | " .
- wfNumLink( $offset, 100, $link, $query ) . " | " .
- wfNumLink( $offset, 250, $link, $query ) . " | " .
+ $nums = wfNumLink( $offset, 20, $link , $query ) . ' | ' .
+ wfNumLink( $offset, 50, $link, $query ) . ' | ' .
+ wfNumLink( $offset, 100, $link, $query ) . ' | ' .
+ wfNumLink( $offset, 250, $link, $query ) . ' | ' .
wfNumLink( $offset, 500, $link, $query );
- return wfMsg( "viewprevnext", $plink, $nlink, $nums );
+ return wfMsg( 'viewprevnext', $plink, $nlink, $nums );
}
-function wfNumLink( $offset, $limit, $link, $query = "" )
+function wfNumLink( $offset, $limit, $link, $query = '' )
{
global $wgUser, $wgLang;
- if ( "" == $query ) { $q = ""; }
+ if ( '' == $query ) { $q = ''; }
else { $q = "{$query}&"; }
$q .= "limit={$limit}&offset={$offset}";
$fmtLimit = $wgLang->formatNum( $limit );
- $s = "<a href=\"" . wfLocalUrlE( $link, $q ) . "\">{$fmtLimit}</a>";
+ $s = '<a href="' . wfLocalUrlE( $link, $q ) . "\">{$fmtLimit}</a>";
return $s;
}
@@ -630,9 +651,9 @@ function wfClientAcceptsGzip() {
# FIXME: we may want to blacklist some broken browsers
if( preg_match(
'/\bgzip(?:;(q)=([0-9]+(?:\.[0-9]+)))?\b/',
- $_SERVER["HTTP_ACCEPT_ENCODING"],
+ $_SERVER['HTTP_ACCEPT_ENCODING'],
$m ) ) {
- if( ( $m[1] == "q" ) && ( $m[2] == 0 ) ) return false;
+ if( ( $m[1] == 'q' ) && ( $m[2] == 0 ) ) return false;
wfDebug( " accepts gzip\n" );
return true;
}
@@ -641,12 +662,12 @@ function wfClientAcceptsGzip() {
}
# Yay, more global functions!
-function wfCheckLimits( $deflimit = 50, $optionname = "rclimit" ) {
+function wfCheckLimits( $deflimit = 50, $optionname = 'rclimit' ) {
global $wgUser, $wgRequest;
$limit = $wgRequest->getInt( 'limit', 0 );
if( $limit < 0 ) $limit = 0;
- if( ( $limit == 0 ) && ( $optionname != "" ) ) {
+ if( ( $limit == 0 ) && ( $optionname != '' ) ) {
$limit = (int)$wgUser->getOption( $optionname );
}
if( $limit <= 0 ) $limit = $deflimit;
@@ -668,13 +689,13 @@ function wfCheckLimits( $deflimit = 50, $optionname = "rclimit" ) {
function wfEscapeWikiText( $text )
{
$text = str_replace(
- array( '[', '|', "'", 'ISBN ' , '://' , "\n=" ),
+ array( '[', '|', "'", 'ISBN ' , '://' , "\n=" ),
array( '&#91;', '&#124;', '&#39;', 'ISBN&#32;', '&#58;//' , "\n&#61;" ),
htmlspecialchars($text) );
return $text;
}
-function wfQuotedPrintable( $string, $charset = "" )
+function wfQuotedPrintable( $string, $charset = '' )
{
# Probably incomplete; see RFC 2045
if( empty( $charset ) ) {
@@ -682,19 +703,19 @@ function wfQuotedPrintable( $string, $charset = "" )
$charset = $wgInputEncoding;
}
$charset = strtoupper( $charset );
- $charset = str_replace( "ISO-8859", "ISO8859", $charset ); // ?
+ $charset = str_replace( 'ISO-8859', 'ISO8859', $charset ); // ?
$illegal = '\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\xff=';
$replace = $illegal . '\t ?_';
if( !preg_match( "/[$illegal]/", $string ) ) return $string;
$out = "=?$charset?Q?";
$out .= preg_replace( "/([$replace])/e", 'sprintf("=%02X",ord("$1"))', $string );
- $out .= "?=";
+ $out .= '?=';
return $out;
}
function wfTime(){
- $st = explode( " ", microtime() );
+ $st = explode( ' ', microtime() );
return (float)$st[0] + (float)$st[1];
}
@@ -714,11 +735,10 @@ function wfSetVar( &$dest, $source )
}
# Sets dest to a reference to source and returns the original dest
+# Pity that doesn't work in PHP
function &wfSetRef( &$dest, &$source )
{
- $temp =& $dest;
- $dest =& $source;
- return $temp;
+ die( "You can't rebind a variable in the caller's scope" );
}
# This function takes two arrays as input, and returns a CGI-style string, e.g.
@@ -730,11 +750,11 @@ function wfArrayToCGI( $array1, $array2 = NULL )
$array1 = $array1 + $array2;
}
- $cgi = "";
+ $cgi = '';
foreach ( $array1 as $key => $value ) {
- if ( "" !== $value ) {
- if ( "" != $cgi ) {
- $cgi .= "&";
+ if ( '' !== $value ) {
+ if ( '' != $cgi ) {
+ $cgi .= '&';
}
$cgi .= "{$key}={$value}";
}
@@ -752,15 +772,15 @@ function wfEscapeShellArg( )
{
$args = func_get_args();
$first = true;
- $retVal = "";
+ $retVal = '';
foreach ( $args as $arg ) {
if ( !$first ) {
- $retVal .= " ";
+ $retVal .= ' ';
} else {
$first = false;
}
- if (substr(php_uname(), 0, 7) == "Windows") {
+ if ( wfIsWindows() ) {
$retVal .= '"' . str_replace( '"','\"', $arg ) . '"';
} else {
$retVal .= escapeshellarg( $arg );
@@ -782,21 +802,21 @@ function wfMerge( $old, $mine, $yours, &$result ){
}
# Make temporary files
- $td = "/tmp/";
- $oldtextFile = fopen( $oldtextName = tempnam( $td, "merge-old-" ), "w" );
- $mytextFile = fopen( $mytextName = tempnam( $td, "merge-mine-" ), "w" );
- $yourtextFile = fopen( $yourtextName = tempnam( $td, "merge-your-" ), "w" );
+ $td = '/tmp/';
+ $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ), 'w' );
+ $mytextFile = fopen( $mytextName = tempnam( $td, 'merge-mine-' ), 'w' );
+ $yourtextFile = fopen( $yourtextName = tempnam( $td, 'merge-your-' ), 'w' );
fwrite( $oldtextFile, $old ); fclose( $oldtextFile );
fwrite( $mytextFile, $mine ); fclose( $mytextFile );
fwrite( $yourtextFile, $yours ); fclose( $yourtextFile );
# Check for a conflict
- $cmd = wfEscapeShellArg( $wgDiff3 ) . " -a --overlap-only " .
- wfEscapeShellArg( $mytextName ) . " " .
- wfEscapeShellArg( $oldtextName ) . " " .
- wfEscapeShellArg( $yourtextName );
- $handle = popen( $cmd, "r" );
+ $cmd = wfEscapeShellArg( $wgDiff3 ) . ' -a --overlap-only ' .
+ wfEscapeShellArg( $mytextName ) . ' ' .
+ wfEscapeShellArg( $oldtextName ) . ' ' .
+ wfEscapeShellArg( $yourtextName );
+ $handle = popen( $cmd, 'r' );
if( fgets( $handle ) ){
$conflict = true;
@@ -806,10 +826,10 @@ function wfMerge( $old, $mine, $yours, &$result ){
pclose( $handle );
# Merge differences
- $cmd = wfEscapeShellArg( $wgDiff3 ) . " -a -e --merge " .
+ $cmd = wfEscapeShellArg( $wgDiff3 ) . ' -a -e --merge ' .
wfEscapeShellArg( $mytextName, $oldtextName, $yourtextName );
- $handle = popen( $cmd, "r" );
- $result = "";
+ $handle = popen( $cmd, 'r' );
+ $result = '';
do {
$data = fread( $handle, 8192 );
if ( strlen( $data ) == 0 ) {
@@ -843,13 +863,13 @@ function wfHttpError( $code, $label, $desc ) {
# Don't send content if it's a HEAD request.
if( $_SERVER['REQUEST_METHOD'] == 'HEAD' ) {
- header( "Content-type: text/plain" );
+ header( 'Content-type: text/plain' );
print "$desc\n";
}
}
# Converts an Accept-* header into an array mapping string values to quality factors
-function wfAcceptToPrefs( $accept, $def = "*/*" ) {
+function wfAcceptToPrefs( $accept, $def = '*/*' ) {
# No arg means accept anything (per HTTP spec)
if( !$accept ) {
return array( $def => 1 );
@@ -857,11 +877,11 @@ function wfAcceptToPrefs( $accept, $def = "*/*" ) {
$prefs = array();
- $parts = explode( ",", $accept );
+ $parts = explode( ',', $accept );
foreach( $parts as $part ) {
# FIXME: doesn't deal with params like 'text/html; level=1'
- @list( $value, $qpart ) = explode( ";", $part );
+ @list( $value, $qpart ) = explode( ';', $part );
if( !isset( $qpart ) ) {
$prefs[$value] = 1;
} elseif( preg_match( '/q\s*=\s*(\d*\.\d+)/', $qpart, $match ) ) {
@@ -933,4 +953,14 @@ function wfArrayLookup( $a, $b )
return array_flip( array_intersect( array_flip( $a ), array_keys( $b ) ) );
}
+# Since Windows is so different to any of the other popular OSes, it seems appropriate
+# to have a simple way to test for its presence
+function wfIsWindows() {
+ if (substr(php_uname(), 0, 7) == 'Windows') {
+ return true;
+ } else {
+ return false;
+ }
+}
+
?>
diff --git a/includes/HistoryBlob.php b/includes/HistoryBlob.php
new file mode 100644
index 000000000000..cf170b759531
--- /dev/null
+++ b/includes/HistoryBlob.php
@@ -0,0 +1,64 @@
+<?php
+
+# Pure virtual parent
+class HistoryBlob
+{
+ function setMeta() {}
+ function getMeta() {}
+ function addItem() {}
+ function getItem() {}
+}
+
+# The real object
+class ConcatenatedGzipHistoryBlob
+{
+ /* private */ var $mVersion = 0, $mCompressed = false, $mItems = array();
+
+ function HistoryBlob() {
+ if ( !function_exists( 'gzdeflate' ) ) {
+ die( "Need zlib support to read or write this kind of history object (ConcatenatedGzipHistoryBlob)\n" );
+ }
+ }
+
+ function setMeta( $metaData ) {
+ $this->uncompress();
+ $this->mItems['meta'] = $metaData;
+ }
+
+ function getMeta() {
+ $this->uncompress();
+ return $this->mItems['meta'];
+ }
+
+ function addItem( $text ) {
+ $this->uncompress();
+ $this->mItems[md5($text)] = $text;
+ }
+
+ function getItem( $hash ) {
+ $this->compress();
+ return $this->mItems[$hash];
+ }
+
+ function compress() {
+ if ( !$this->mCompressed ) {
+ $this->mItems = gzdeflate( serialize( $this->mItems ) );
+ $this->mCompressed = true;
+ }
+ }
+
+ function uncompress() {
+ if ( $this->mCompressed ) {
+ $this->mItems = unserialize( gzinflate( $this->mItems ) );
+ }
+ }
+
+ function __sleep() {
+ compress();
+ }
+
+ function __wakeup() {
+ uncompress();
+ }
+}
+?>
diff --git a/includes/Image.php b/includes/Image.php
index d0293a5443c7..27eeb9d72e3f 100644
--- a/includes/Image.php
+++ b/includes/Image.php
@@ -35,16 +35,17 @@ class Image
if ( $this->fileExists = file_exists( $this->imagePath ) ) // Sic!, "=" is intended
{
- $gis = getimagesize( $this->imagePath );
- $this->width = $gis[0];
- $this->height = $gis[1];
- $this->type = $gis[2];
- $this->attr = $gis[3];
- if ( isset( $gis["bits"] ) )
- {
- $this->bits = $gis["bits"];
- } else {
- $this->bits = 0;
+ @$gis = getimagesize( $this->imagePath );
+ if( $gis !== false ) {
+ $this->width = $gis[0];
+ $this->height = $gis[1];
+ $this->type = $gis[2];
+ $this->attr = $gis[3];
+ if ( isset( $gis["bits"] ) ) {
+ $this->bits = $gis["bits"];
+ } else {
+ $this->bits = 0;
+ }
}
}
$this->historyLine = 0;
diff --git a/includes/ImagePage.php b/includes/ImagePage.php
index 164abb5a370f..6e8d72b6c20e 100644
--- a/includes/ImagePage.php
+++ b/includes/ImagePage.php
@@ -67,7 +67,7 @@ class ImagePage extends Article {
$line = $this->img->nextHistoryLine();
$s .= $sk->imageHistoryLine( true, $line->img_timestamp,
- $this->mTitle->getText(), $line->img_user,
+ $this->mTitle->getDBkey(), $line->img_user,
$line->img_user_text, $line->img_size, $line->img_description );
while ( $line = $this->img->nextHistoryLine() ) {
@@ -139,9 +139,9 @@ class ImagePage extends Article {
}
if ( !is_null( $image ) ) {
- $q = "&image={$image}";
+ $q = "&image=" . urlencode( $image );
} else if ( !is_null( $oldimage ) ) {
- $q = "&oldimage={$oldimage}";
+ $q = "&oldimage=" . urlencode( $oldimage );
} else {
$q = "";
}
diff --git a/includes/LinkCache.php b/includes/LinkCache.php
index 8f41cccf7e51..cd0c0879e4e8 100644
--- a/includes/LinkCache.php
+++ b/includes/LinkCache.php
@@ -171,6 +171,7 @@ class LinkCache {
if ( $wgEnablePersistentLC ) {
if( $this->fillFromLinkscc( $id ) ){
+ wfProfileOut( $fname );
return;
}
}
@@ -301,35 +302,61 @@ class LinkCache {
}
/* private */ function saveToLinkscc( $pid ){
- global $wgCompressedPersistentLC;
+ global $wgCompressedPersistentLC, $wgIsMySQL;
if( $wgCompressedPersistentLC and function_exists( "gzcompress" ) ) {
$ser = wfStrencode( gzcompress( serialize( $this ), 3 ));
} else {
$ser = wfStrencode( serialize( $this ) );
}
- wfQuery("REPLACE INTO linkscc(lcc_pageid,lcc_cacheobj) " .
- "VALUES({$pid}, '{$ser}')", DB_WRITE);
+ if ($wgIsMySQL) {
+ wfQuery("REPLACE INTO linkscc(lcc_pageid,lcc_cacheobj) " .
+ "VALUES({$pid}, '{$ser}')", DB_WRITE);
+ } else {
+ wfQuery("DELETE FROM linkscc WHERE lcc_pageid={$pid}",DB_WRITE);
+ wfQuery("INSERT INTO linkscc(lcc_pageid,lcc_cacheobj) " .
+ "VALUES({$pid}, '{$ser}')", DB_WRITE);
+ }
}
# $pid is a page id
/* static */ function linksccClearLinksTo( $pid ){
- $pid = intval( $pid );
- wfQuery("DELETE linkscc FROM linkscc,links ".
- "WHERE lcc_pageid=links.l_from AND l_to={$pid}", DB_WRITE);
- wfQuery("DELETE FROM linkscc WHERE lcc_pageid='{$pid}'", DB_WRITE);
+ global $wgEnablePersistentLC, $wgIsMySQL;
+ if ( $wgEnablePersistentLC ) {
+ $pid = intval( $pid );
+ if ($wgIsMySQL) {
+ wfQuery("DELETE linkscc FROM linkscc,links ".
+ "WHERE lcc_pageid=links.l_from AND l_to={$pid}", DB_WRITE);
+ } else {
+ wfQuery("DELETE FROM linkscc WHERE lcc_pageid IN ".
+ "(SELECT l_from FROM links WHERE l_to={$pid})", DB_WRITE);
+ }
+ wfQuery("DELETE FROM linkscc WHERE lcc_pageid='{$pid}'", DB_WRITE);
+ }
}
# $title is a prefixed db title, for example like Title->getPrefixedDBkey() returns.
/* static */ function linksccClearBrokenLinksTo( $title ){
- $title = wfStrencode( $title );
- wfQuery("DELETE linkscc FROM linkscc,brokenlinks ".
- "WHERE lcc_pageid=bl_from AND bl_to='{$title}'", DB_WRITE);
+ global $wgEnablePersistentLC,$wgIsMySQL;
+ if ( $wgEnablePersistentLC ) {
+ $title = wfStrencode( $title );
+ if ($wgIsMySQL) {
+ wfQuery("DELETE linkscc FROM linkscc,brokenlinks ".
+ "WHERE lcc_pageid=bl_from AND bl_to='{$title}'", DB_WRITE);
+ } else {
+ wfQuery("DELETE FROM linkscc WHERE lcc_pageid IN ".
+ "(SELECT bl_from FROM brokenlinks ".
+ "WHERE bl_to='{$title}')",DB_WRITE);
+ }
+ }
}
# $pid is a page id
/* static */ function linksccClearPage( $pid ){
- $pid = intval( $pid );
- wfQuery("DELETE FROM linkscc WHERE lcc_pageid='{$pid}'", DB_WRITE);
+ global $wgEnablePersistentLC;
+ if ( $wgEnablePersistentLC ) {
+ $pid = intval( $pid );
+ wfQuery("DELETE FROM linkscc WHERE lcc_pageid='{$pid}'", DB_WRITE);
+ }
}
}
?>
diff --git a/includes/LoadBalancer.php b/includes/LoadBalancer.php
index 3df2ac58c604..94f4f55cff0d 100644
--- a/includes/LoadBalancer.php
+++ b/includes/LoadBalancer.php
@@ -1,10 +1,27 @@
<?php
# Database load balancing object
+# Valid database indexes
+# Operation-based indexes
+define( "DB_READ", -1 ); # Read from the slave (or only server)
+define( "DB_WRITE", -2 ); # Write to master (or only server)
+define( "DB_LAST", -3 ); # Whatever database was used last
+
+# Task-based indexes
+# ***NOT USED YET, EXPERIMENTAL***
+# These may be defined in $wgDBservers. If they aren't, the default reader or writer will be used
+# Even numbers are always readers, odd numbers are writers
+define( "DB_TASK_FIRST", 1000 ); # First in list
+define( "DB_SEARCH_R", 1000 ); # Search read
+define( "DB_SEARCH_W", 1001 ); # Search write
+define( "DB_ASKSQL_R", 1002 ); # Special:Asksql read
+define( "DB_WATCHLIST_R", 1004 ); # Watchlist read
+define( "DB_TASK_LAST", 1004) ; # Last in list
+
class LoadBalancer {
/* private */ var $mServers, $mConnections, $mLoads;
/* private */ var $mUser, $mPassword, $mDbName, $mFailFunction;
- /* private */ var $mForce, $mReadIndex;
+ /* private */ var $mForce, $mReadIndex, $mLastConn;
function LoadBalancer()
{
@@ -17,6 +34,7 @@ class LoadBalancer {
$this->mFailFunction = false;
$this->mReadIndex = -1;
$this->mForce = -1;
+ $this->mLastConn = false;
}
function newFromParams( $servers, $loads, $user, $password, $dbName, $failFunction = false )
@@ -38,6 +56,7 @@ class LoadBalancer {
$this->mWriteIndex = -1;
$this->mForce = -1;
$this->mConnections = array();
+ $this->mLastConn = false;
wfSeedRandom();
}
@@ -53,7 +72,8 @@ class LoadBalancer {
foreach ( $weights as $w ) {
$sum += $w;
}
- $rand = mt_rand() / RAND_MAX * $sum;
+ $max = mt_getrandmax();
+ $rand = mt_rand(0, $max) / $max * $sum;
$sum = 0;
foreach ( $weights as $i => $w ) {
@@ -77,8 +97,10 @@ class LoadBalancer {
# don't work
$loads = $this->mLoads;
do {
- $i = pickRandom( $loads );
+ $i = $this->pickRandom( $loads );
if ( $i !== false ) {
+ wfDebug( "Using reader #$i: {$this->mServers[$i]}\n" );
+
$conn =& $this->getConnection( $i );
if ( !$conn->isOpen() ) {
unset( $loads[$i] );
@@ -96,21 +118,49 @@ class LoadBalancer {
}
return $conn;
}
-
+
function &getConnection( $i, $fail = false )
{
- if ( !array_key_exists( $i, $this->mConnections) || !$this->mConnections[$i]->isOpen() ) {
- $this->mConnections[$i] = Database::newFromParams( $this->mServers[$i], $this->mUser,
- $this->mPassword, $this->mDbName, 1 );
- }
- if ( !$this->mConnections[$i]->isOpen() ) {
- wfDebug( "Failed to connect to database $i at {$this->mServers[$i]}\n" );
- if ( $fail ) {
- $this->reportConnectionError( $this->mConnections[$i] );
+ /*
+ # Task-based index
+ if ( $i >= DB_TASK_FIRST && $i < DB_TASK_LAST ) {
+ if ( $i % 2 ) {
+ # Odd index use writer
+ $i = DB_WRITE;
+ } else {
+ # Even index use reader
+ $i = DB_READ;
+ }
+ }*/
+
+ # Operation-based index
+ # Note, getReader() and getWriter() will re-enter this function
+ if ( $i == DB_READ ) {
+ $this->mLastConn =& $this->getReader();
+ } elseif ( $i == DB_WRITE ) {
+ $this->mLastConn =& $this->getWriter();
+ } elseif ( $i == DB_LAST ) {
+ # Just use $this->mLastConn, which should already be set
+ if ( $this->mLastConn === false ) {
+ # Oh dear, not set, best to use the writer for safety
+ $this->mLastConn =& $this->getWriter();
+ }
+ } else {
+ # Explicit index
+ if ( !array_key_exists( $i, $this->mConnections) || !$this->mConnections[$i]->isOpen() ) {
+ $this->mConnections[$i] = Database::newFromParams( $this->mServers[$i], $this->mUser,
+ $this->mPassword, $this->mDbName, 1 );
+ }
+ if ( !$this->mConnections[$i]->isOpen() ) {
+ wfDebug( "Failed to connect to database $i at {$this->mServers[$i]}\n" );
+ if ( $fail ) {
+ $this->reportConnectionError( $this->mConnections[$i] );
+ }
+ $this->mConnections[$i] = false;
}
- $this->mConnections[$i] = false;
+ $this->mLastConn =& $this->mConnections[$i];
}
- return $this->mConnections[$i];
+ return $this->mLastConn;
}
function reportConnectionError( &$conn )
@@ -129,8 +179,8 @@ class LoadBalancer {
function &getWriter()
{
$c =& $this->getConnection( 0 );
- if ( !$c->isOpen() ) {
- reportConnectionError( $conn );
+ if ( $c === false || !$c->isOpen() ) {
+ $this->reportConnectionError( $c );
$c = false;
}
return $c;
@@ -140,4 +190,9 @@ class LoadBalancer {
{
$this->mForce = $i;
}
+
+ function haveIndex( $i )
+ {
+ return array_key_exists( $i, $this->mServers );
+ }
}
diff --git a/includes/MagicWord.php b/includes/MagicWord.php
index 9089d5108a2c..bb7b7c1640b3 100644
--- a/includes/MagicWord.php
+++ b/includes/MagicWord.php
@@ -110,7 +110,7 @@ class MagicWord {
$this->mRegexStart = "/^{$this->mBaseRegex}/{$case}";
$this->mVariableRegex = str_replace( "\\$1", "([$variableClass]*?)", $this->mRegex );
$this->mVariableStartToEndRegex = str_replace( "\\$1", "([$variableClass]*?)",
- "/^{$this->mBaseRegex}$/{$case}" );
+ "/^({$this->mBaseRegex})$/{$case}" );
}
# Gets a regex representing matching the word
diff --git a/includes/Math.php b/includes/Math.php
index 5946061fb48f..8b03af6adcbb 100644
--- a/includes/Math.php
+++ b/includes/Math.php
@@ -30,7 +30,7 @@ class MathRenderer {
if( $this->mode == MW_MATH_SOURCE ) {
# No need to render or parse anything more!
- return ('$ '.htmlspecialchars( $tex ).' $');
+ return ('$ '.htmlspecialchars( $this->tex ).' $');
}
if( !$this->_recall() ) {
@@ -182,7 +182,7 @@ class MathRenderer {
(($this->mode == MW_MATH_MODERN || $this->mode == MW_MATH_MATHML) && ($this->conservativeness == 0))) {
return $this->_linkToMathImage();
} else {
- return $this->html;
+ return '<span class="texhtml">'.$this->html.'</span>';
}
}
diff --git a/includes/MessageCache.php b/includes/MessageCache.php
index 66285e18b936..4aee8583134d 100755
--- a/includes/MessageCache.php
+++ b/includes/MessageCache.php
@@ -81,7 +81,7 @@ class MessageCache
function loadFromDB()
{
$fname = "MessageCache::loadFromDB";
- $sql = "SELECT cur_title,cur_text FROM cur WHERE cur_namespace=" . NS_MEDIAWIKI;
+ $sql = "SELECT cur_title,cur_text FROM cur WHERE cur_is_redirect=0 AND cur_namespace=" . NS_MEDIAWIKI;
$res = wfQuery( $sql, DB_READ, $fname );
$this->mCache = array();
diff --git a/includes/ObjectCache.php b/includes/ObjectCache.php
index 00864c6b16b1..ce511ff37b10 100644
--- a/includes/ObjectCache.php
+++ b/includes/ObjectCache.php
@@ -1,4 +1,6 @@
<?php
+# $Id$
+#
# Copyright (C) 2003-2004 Brion Vibber <brion@pobox.com>
# http://www.mediawiki.org/
#
@@ -69,8 +71,10 @@ class /* abstract */ BagOStuff {
}
function add($key, $value, $exptime=0) {
- if( $this->get($key) === false )
+ if( $this->get($key) == false ) {
$this->set($key, $value, $exptime);
+ return true;
+ }
}
function add_multi($hash, $exptime=0) {
@@ -114,7 +118,7 @@ class /* abstract */ BagOStuff {
function _debug($text) {
if($this->debugmode)
- echo "\ndebug: $text\n";
+ wfDebug("BagOStuff debug: $text\n");
}
}
@@ -187,9 +191,9 @@ class /* abstract */ SqlBagOStuff extends BagOStuff {
$this->_debug("get: ** error: " . $this->_dberror($res) . " **");
return false;
}
- if($arr = $this->_fetchrow($res)) {
- $this->_debug("get: retrieved data; exp time is " . $arr['exptime']);
- return unserialize($arr['value']);
+ if($row=$this->_fetchobject($res)) {
+ $this->_debug("get: retrieved data; exp time is " . $row->exptime);
+ return unserialize($row->value);
} else {
$this->_debug("get: no matching rows");
}
@@ -208,8 +212,8 @@ class /* abstract */ SqlBagOStuff extends BagOStuff {
}
$this->delete( $key );
$this->_query(
- "INSERT INTO $0 (keyname,value,exptime) VALUES('$1','$2',$exp)",
- $key, serialize(&$value));
+ "INSERT INTO $0 (keyname,value,exptime) VALUES('$1','$2','$exp')",
+ $key, serialize($value));
return true; /* ? */
}
@@ -230,7 +234,7 @@ class /* abstract */ SqlBagOStuff extends BagOStuff {
$sql);
}
$res = $this->_doquery($sql);
- if($res === false) {
+ if($res == false) {
$this->_debug("query failed: " . $this->_dberror($res));
}
return $res;
@@ -269,7 +273,8 @@ class /* abstract */ SqlBagOStuff extends BagOStuff {
function expireall() {
/* Remove any items that have expired */
- $this->_query( "DELETE FROM $0 WHERE exptime<=NOW()" );
+ $now=$this->_fromunixtime(time());
+ $this->_query( "DELETE FROM $0 WHERE exptime<'$now'" );
}
function deleteall() {
@@ -278,42 +283,27 @@ class /* abstract */ SqlBagOStuff extends BagOStuff {
}
}
-class MysqlBagOStuff extends SqlBagOStuff {
+class MediaWikiBagOStuff extends SqlBagOStuff {
function _doquery($sql) {
- return mysql_query($sql);
+ return wfQuery($sql, DB_READ, "MediaWikiBagOStuff:_doquery");
}
- function _fetchrow($result) {
- return mysql_fetch_array($result);
+ function _fetchobject($result) {
+ return wfFetchObject($result);
}
function _freeresult($result) {
- return mysql_free_result($result);
+ return wfFreeResult($result);
}
function _dberror($result) {
- if($result)
- return mysql_error($result);
- else
- return mysql_error();
+ return wfLastError();
}
-
function _maxdatetime() {
- return "'9999-12-31 12:59:59'";
+ return "9999-12-31 12:59:59";
}
-
function _fromunixtime($ts) {
- return "FROM_UNIXTIME($ts)";
+ return gmdate( "Y-m-d H:i:s", $ts );
}
-
function _strencode($s) {
- return mysql_escape_string($s);
- }
-}
-
-class MediaWikiBagOStuff extends MysqlBagOStuff {
- function _doquery($sql) {
- return wfQuery($sql, DB_READ, "MediaWikiBagOStuff:_doquery");
- }
- function _freeresult($result) {
- return wfFreeResult($result);
+ return wfStrEncode($s);
}
}
diff --git a/includes/OutputPage.php b/includes/OutputPage.php
index 7860a4228f23..50d0d38bfe48 100644
--- a/includes/OutputPage.php
+++ b/includes/OutputPage.php
@@ -181,10 +181,24 @@ class OutputPage {
}
function getLanguageLinks() {
- global $wgTitle, $wgLanguageCode;
- global $wgDBconnection, $wgDBname;
return $this->mLanguageLinks;
}
+ function addLanguageLinks($newLinkArray) {
+ $this->mLanguageLinks += $newLinkArray;
+ }
+ function setLanguageLinks($newLinkArray) {
+ $this->mLanguageLinks = $newLinkArray;
+ }
+ function getCategoryLinks() {
+ return $this->mCategoryLinks;
+ }
+ function addCategoryLinks($newLinkArray) {
+ $this->mCategoryLinks += $newLinkArray;
+ }
+ function setCategoryLinks($newLinkArray) {
+ $this->mCategoryLinks += $newLinkArray;
+ }
+
function suppressQuickbar() { $this->mSuppressQuickbar = true; }
function isQuickbarSuppressed() { return $this->mSuppressQuickbar; }
@@ -204,26 +218,30 @@ class OutputPage {
function addWikiText( $text, $linestart = true, $cacheArticle = NULL )
{
global $wgParser, $wgParserCache, $wgUser, $wgTitle;
-
- $parserOutput = false;
+
+ $parserOutput = $wgParser->parse( $text, $wgTitle, $this->mParserOptions, $linestart );
if ( $cacheArticle ) {
- $parserOutput = $wgParserCache->get( $cacheArticle, $wgUser );
- }
-
- if ( $parserOutput === false ) {
- $parserOutput = $wgParser->parse( $text, $wgTitle, $this->mParserOptions, $linestart );
- if ( $cacheArticle ) {
- $wgParserCache->save( $parserOutput, $cacheArticle, $wgUser );
- }
+ $wgParserCache->save( $parserOutput, $cacheArticle, $wgUser );
}
$this->mLanguageLinks += $parserOutput->getLanguageLinks();
$this->mCategoryLinks += $parserOutput->getCategoryLinks();
-
$this->addHTML( $parserOutput->getText() );
-
}
+ function tryParserCache( $article, $user ) {
+ global $wgParserCache;
+ $parserOutput = $wgParserCache->get( $article, $user );
+ if ( $parserOutput !== false ) {
+ $this->mLanguageLinks += $parserOutput->getLanguageLinks();
+ $this->mCategoryLinks += $parserOutput->getCategoryLinks();
+ $this->addHTML( $parserOutput->getText() );
+ return true;
+ } else {
+ return false;
+ }
+ }
+
# Set the maximum cache time on the Squid in seconds
function setSquidMaxage( $maxage ) {
$this->mSquidMaxage = $maxage;
@@ -407,8 +425,22 @@ class OutputPage {
list( $usec, $sec ) = explode( " ", $wgRequestTime );
$start = (float)$sec + (float)$usec;
$elapsed = $now - $start;
- $com = sprintf( "<!-- Time since request: %01.2f secs. -->",
- $elapsed );
+
+ # Use real server name if available, so we know which machine
+ # in a server farm generated the current page.
+ if ( function_exists( "posix_uname" ) ) {
+ $uname = @posix_uname();
+ } else {
+ $uname = false;
+ }
+ if( is_array( $uname ) && isset( $uname['nodename'] ) ) {
+ $hostname = $uname['nodename'];
+ } else {
+ # This may be a virtual server.
+ $hostname = $_SERVER['SERVER_NAME'];
+ }
+ $com = sprintf( "<!-- Served by %s in %01.2f secs. -->",
+ $hostname, $elapsed );
return $com;
}
@@ -486,7 +518,7 @@ class OutputPage {
$this->returnToMain(); # Flip back to the main page after 10 seconds.
}
- function databaseError( $fname, &$conn )
+ function databaseError( $fname, $sql, $error, $errno )
{
global $wgUser, $wgCommandLineMode;
@@ -501,10 +533,10 @@ class OutputPage {
$msg = wfMsgNoDB( "dberrortext" );
}
- $msg = str_replace( "$1", htmlspecialchars( $conn->lastQuery() ), $msg );
+ $msg = str_replace( "$1", htmlspecialchars( $sql ), $msg );
$msg = str_replace( "$2", htmlspecialchars( $fname ), $msg );
- $msg = str_replace( "$3", $conn->lastErrno(), $msg );
- $msg = str_replace( "$4", htmlspecialchars( $conn->lastError() ), $msg );
+ $msg = str_replace( "$3", $errno, $msg );
+ $msg = str_replace( "$4", htmlspecialchars( $error ), $msg );
if ( $wgCommandLineMode || !is_object( $wgUser )) {
print "$msg\n";
@@ -586,6 +618,9 @@ class OutputPage {
$this->fatalError( wfMsg( "filenotfound", $name ) );
}
+ // return from error messages or notes
+ // auto: automatically redirect the user after 10 seconds
+ // returnto: page title to return to. Default is Main Page.
function returnToMain( $auto = true, $returnto = NULL )
{
global $wgUser, $wgOut, $wgRequest;
diff --git a/includes/PageHistory.php b/includes/PageHistory.php
index 49b42f3f2a7e..3eeaa9d419fa 100644
--- a/includes/PageHistory.php
+++ b/includes/PageHistory.php
@@ -17,7 +17,7 @@ class PageHistory {
function history()
{
- global $wgUser, $wgOut, $wgLang;
+ global $wgUser, $wgOut, $wgLang, $wgIsMySQL, $wgIsPg;
# If page hasn't changed, client can cache this
@@ -54,12 +54,14 @@ class PageHistory {
$namespace = $this->mTitle->getNamespace();
$title = $this->mTitle->getText();
+ $use_index=$wgIsMySQL?"USE INDEX (name_title_timestamp)":"";
+ $oldtable=$wgIsPg?'"old"':'old';
$sql = "SELECT old_id,old_user," .
"old_comment,old_user_text,old_timestamp,old_minor_edit ".
- "FROM old USE INDEX (name_title_timestamp) " .
+ "FROM $oldtable $use_index " .
"WHERE old_namespace={$namespace} AND " .
"old_title='" . wfStrencode( $this->mTitle->getDBkey() ) . "' " .
- "ORDER BY inverse_timestamp LIMIT $rawoffset, $limitplus";
+ "ORDER BY inverse_timestamp".wfLimitResult($limitplus,$rawoffset);
$res = wfQuery( $sql, DB_READ, $fname );
$revs = wfNumRows( $res );
@@ -77,6 +79,12 @@ class PageHistory {
$this->mTitle->getPrefixedText(),
"action=history", $atend );
$s = $numbar;
+ if($this->linesonpage > 0) {
+ $submitpart1 = '<input class="historysubmit" type="submit" accesskey="'.wfMsg('accesskey-compareselectedversions').
+ '" title="'.wfMsg('tooltip-compareselectedversions').'" value="'.wfMsg('compareselectedversions').'"';
+ $this->submitbuttonhtml1 = $submitpart1 . ' />';
+ $this->submitbuttonhtml2 = $submitpart1 . ' id="historysubmit" />';
+ }
$s .= $this->beginHistoryList();
$counter = 1;
if( $offset == 0 ){
@@ -110,9 +118,10 @@ class PageHistory {
global $wgTitle;
$this->lastdate = $this->lastline = "";
$s = "\n<p>" . wfMsg( "histlegend" ).'</p>';
- $s .="\n<form id=\"pagehistory\" name=\"pagehistory\" action=\"" . $wgTitle->getFullURL("-") . "\" method=\"get\">";
- $s .= "<input type=\"hidden\" name=\"title\" value=\"".htmlspecialchars($wgTitle->getPrefixedDbKey())."\"/>\n";
- $s .= "" . "\n<ul>";
+ $s .="\n<form action=\"" . $wgTitle->escapeLocalURL( '-' ) . "\" method=\"get\">";
+ $s .= "<input type=\"hidden\" name=\"title\" value=\"".wfEscapeHTML($wgTitle->getPrefixedDbKey())."\"/>\n";
+ $s .= !empty($this->submitbuttonhtml1) ? $this->submitbuttonhtml1."\n":'';
+ $s .= "" . "\n<ul id=\"pagehistory\" >";
return $s;
}
@@ -121,11 +130,8 @@ class PageHistory {
$last = wfMsg( "last" );
$s = $skip ? "" : preg_replace( "/!OLDID![0-9]+!/", $last, $this->lastline );
- $s .= "</ul>\n";
- if( $this->linesonpage > 1) {
- $s .= '<button type="submit" accesskey="'.wfMsg('accesskey-compareselectedversions').
- '" title="'.wfMsg('tooltip-compareselectedversions').'">'.wfMsg('compareselectedversions')."</button><br/><br/>\n";
- }
+ $s .= "</ul>";
+ $s .= !empty($this->submitbuttonhtml2) ? $this->submitbuttonhtml2."\n":'';
$s .= "</form>\n";
return $s;
}
@@ -156,10 +162,10 @@ class PageHistory {
if ( 0 == $u ) {
$ul = $this->mSkin->makeKnownLink( $wgLang->specialPage( "Contributions" ),
- $ut, "target=" . $ut );
+ htmlspecialchars( $ut ), "target=" . urlencode( $ut ) );
} else {
$ul = $this->mSkin->makeLink( $wgLang->getNsText(
- Namespace::getUser() ) . ":{$ut}", $ut );
+ Namespace::getUser() ) . ":{$ut}", htmlspecialchars( $ut ) );
}
$s = "<li>";
diff --git a/includes/Parser.php b/includes/Parser.php
index c345e28eec22..31cb12554a6d 100644
--- a/includes/Parser.php
+++ b/includes/Parser.php
@@ -1,13 +1,6 @@
<?php
-require_once('Tokenizer.php');
-
-if( $GLOBALS['wgUseWikiHiero'] ){
- require_once('extensions/wikihiero/wikihiero.php');
-}
-if( $GLOBALS['wgUseTimeline'] ){
- require_once('extensions/timeline/Timeline.php');
-}
+// require_once('Tokenizer.php');
# PHP Parser
#
@@ -55,6 +48,9 @@ define( "UNIQ_PREFIX", "NaodW29");
class Parser
{
+ # Persistent:
+ var $mTagHooks;
+
# Cleared with clearState():
var $mOutput, $mAutonumber, $mDTopen, $mStripState = array();
var $mVariables, $mIncludeCount, $mArgStack, $mLastSection, $mInPre;
@@ -62,13 +58,12 @@ class Parser
# Temporary:
var $mOptions, $mTitle, $mOutputType;
- function Parser()
- {
+ function Parser() {
+ $this->mTagHooks = array();
$this->clearState();
}
- function clearState()
- {
+ function clearState() {
$this->mOutput = new ParserOutput;
$this->mAutonumber = 0;
$this->mLastSection = "";
@@ -77,6 +72,7 @@ class Parser
$this->mIncludeCount = array();
$this->mStripState = array();
$this->mArgStack = array();
+ $this->mInPre = false;
}
# First pass--just handle <nowiki> sections, pass the rest off
@@ -84,8 +80,7 @@ class Parser
#
# Returns a ParserOutput
#
- function parse( $text, &$title, $options, $linestart = true, $clearState = true )
- {
+ function parse( $text, &$title, $options, $linestart = true, $clearState = true ) {
global $wgUseTidy;
$fname = "Parser::parse";
wfProfileIn( $fname );
@@ -105,10 +100,15 @@ class Parser
# Clean up special characters, only run once, next-to-last before doBlockLevels
if(!$wgUseTidy) {
$fixtags = array(
- "/<hr *>/i" => '<hr/>',
- "/<br *>/i" => '<br/>',
- "/<center *>/i"=>'<div class="center">',
- "/<\\/center *>/i" => '</div>',
+ # french spaces, last one Guillemet-left
+ # only if there is something before the space
+ '/(.) (\\?|:|!|\\302\\273)/i' => '\\1&nbsp;\\2',
+ # french spaces, Guillemet-right
+ "/(\\302\\253) /i"=>"\\1&nbsp;",
+ '/<hr *>/i' => '<hr />',
+ '/<br *>/i' => '<br />',
+ '/<center *>/i' => '<div class="center">',
+ '/<\\/center *>/i' => '</div>',
# Clean up spare ampersands; note that we probably ought to be
# more careful about named entities.
'/&(?!:amp;|#[Xx][0-9A-fa-f]+;|#[0-9]+;|[a-zA-Z0-9]+;)/' => '&amp;'
@@ -116,13 +116,18 @@ class Parser
$text = preg_replace( array_keys($fixtags), array_values($fixtags), $text );
} else {
$fixtags = array(
- "/<center *>/i"=>'<div class="center">',
- "/<\\/center *>/i" => '</div>'
+ # french spaces, last one Guillemet-left
+ '/ (\\?|:|!|\\302\\273)/i' => '&nbsp;\\1',
+ # french spaces, Guillemet-right
+ '/(\\302\\253) /i' => '\\1&nbsp;',
+ '/<center *>/i' => '<div class="center">',
+ '/<\\/center *>/i' => '</div>'
);
$text = preg_replace( array_keys($fixtags), array_values($fixtags), $text );
}
# only once and last
$text = $this->doBlockLevels( $text, $linestart );
+ $text = $this->unstripNoWiki( $text, $this->mStripState );
if($wgUseTidy) {
$text = $this->tidy($text);
}
@@ -131,8 +136,7 @@ class Parser
return $this->mOutput;
}
- /* static */ function getRandomString()
- {
+ /* static */ function getRandomString() {
return dechex(mt_rand(0, 0x7fffffff)) . dechex(mt_rand(0, 0x7fffffff));
}
@@ -152,24 +156,24 @@ class Parser
$content = array( );
}
$n = 1;
- $stripped = "";
+ $stripped = '';
- while ( "" != $text ) {
+ while ( '' != $text ) {
if($tag==STRIP_COMMENTS) {
- $p = preg_split( "/<!--/i", $text, 2 );
+ $p = preg_split( '/<!--/i', $text, 2 );
} else {
$p = preg_split( "/<\\s*$tag\\s*>/i", $text, 2 );
}
$stripped .= $p[0];
- if ( ( count( $p ) < 2 ) || ( "" == $p[1] ) ) {
- $text = "";
+ if ( ( count( $p ) < 2 ) || ( '' == $p[1] ) ) {
+ $text = '';
} else {
if($tag==STRIP_COMMENTS) {
- $q = preg_split( "/-->/i", $p[1], 2 );
+ $q = preg_split( '/-->/i', $p[1], 2 );
} else {
$q = preg_split( "/<\\/\\s*$tag\\s*>/i", $p[1], 2 );
}
- $marker = $rnd . sprintf("%08X", $n++);
+ $marker = $rnd . sprintf('%08X', $n++);
$content[$marker] = $q[0];
$stripped .= $marker;
$text = $q[1];
@@ -187,20 +191,21 @@ class Parser
# will be stripped in addition to other tags. This is important
# for section editing, where these comments cause confusion when
# counting the sections in the wikisource
- function strip( $text, &$state, $stripcomments = false )
- {
+ function strip( $text, &$state, $stripcomments = false ) {
$render = ($this->mOutputType == OT_HTML);
$nowiki_content = array();
- $hiero_content = array();
$math_content = array();
$pre_content = array();
$comment_content = array();
-
+ $ext_content = array();
+
# Replace any instances of the placeholders
$uniq_prefix = UNIQ_PREFIX;
#$text = str_replace( $uniq_prefix, wfHtmlEscapeFirst( $uniq_prefix ), $text );
- $text = Parser::extractTags("nowiki", $text, $nowiki_content, $uniq_prefix);
+
+ # nowiki
+ $text = Parser::extractTags('nowiki', $text, $nowiki_content, $uniq_prefix);
foreach( $nowiki_content as $marker => $content ){
if( $render ){
$nowiki_content[$marker] = wfEscapeHTMLTagsOnly( $content );
@@ -209,16 +214,8 @@ class Parser
}
}
- $text = Parser::extractTags("hiero", $text, $hiero_content, $uniq_prefix);
- foreach( $hiero_content as $marker => $content ){
- if( $render && $GLOBALS['wgUseWikiHiero']){
- $hiero_content[$marker] = WikiHiero( $content, WH_MODE_HTML);
- } else {
- $hiero_content[$marker] = "<hiero>$content</hiero>";
- }
- }
-
- $text = Parser::extractTags("math", $text, $math_content, $uniq_prefix);
+ # math
+ $text = Parser::extractTags('math', $text, $math_content, $uniq_prefix);
foreach( $math_content as $marker => $content ){
if( $render ) {
if( $this->mOptions->getUseTeX() ) {
@@ -231,14 +228,17 @@ class Parser
}
}
- $text = Parser::extractTags("pre", $text, $pre_content, $uniq_prefix);
+ # pre
+ $text = Parser::extractTags('pre', $text, $pre_content, $uniq_prefix);
foreach( $pre_content as $marker => $content ){
if( $render ){
- $pre_content[$marker] = "<pre>" . wfEscapeHTMLTagsOnly( $content ) . "</pre>";
+ $pre_content[$marker] = '<pre>' . wfEscapeHTMLTagsOnly( $content ) . '</pre>';
} else {
$pre_content[$marker] = "<pre>$content</pre>";
}
}
+
+ # Comments
if($stripcomments) {
$text = Parser::extractTags(STRIP_COMMENTS, $text, $comment_content, $uniq_prefix);
foreach( $comment_content as $marker => $content ){
@@ -246,49 +246,75 @@ class Parser
}
}
+ # Extensions
+ foreach ( $this->mTagHooks as $tag => $callback ) {
+ $ext_contents[$tag] = array();
+ $text = Parser::extractTags( $tag, $text, $ext_content[$tag], $uniq_prefix );
+ foreach( $ext_content[$tag] as $marker => $content ) {
+ if ( $render ) {
+ $ext_content[$tag][$marker] = $callback( $content );
+ } else {
+ $ext_content[$tag][$marker] = "<$tag>$content</$tag>";
+ }
+ }
+ }
+
# Merge state with the pre-existing state, if there is one
if ( $state ) {
$state['nowiki'] = $state['nowiki'] + $nowiki_content;
- $state['hiero'] = $state['hiero'] + $hiero_content;
$state['math'] = $state['math'] + $math_content;
$state['pre'] = $state['pre'] + $pre_content;
$state['comment'] = $state['comment'] + $comment_content;
+
+ foreach( $ext_content as $tag => $array ) {
+ if ( array_key_exists( $tag, $state ) ) {
+ $state[$tag] = $state[$tag] + $array;
+ }
+ }
} else {
$state = array(
'nowiki' => $nowiki_content,
- 'hiero' => $hiero_content,
'math' => $math_content,
'pre' => $pre_content,
- 'comment' => $comment_content
- );
+ 'comment' => $comment_content,
+ ) + $ext_content;
}
return $text;
}
- function unstrip( $text, &$state )
- {
+ # always call unstripNoWiki() after this one
+ function unstrip( $text, &$state ) {
# Must expand in reverse order, otherwise nested tags will be corrupted
$contentDict = end( $state );
for ( $contentDict = end( $state ); $contentDict !== false; $contentDict = prev( $state ) ) {
- for ( $content = end( $contentDict ); $content !== false; $content = prev( $contentDict ) ) {
- $text = str_replace( key( $contentDict ), $content, $text );
+ if( key($state) != 'nowiki') {
+ for ( $content = end( $contentDict ); $content !== false; $content = prev( $contentDict ) ) {
+ $text = str_replace( key( $contentDict ), $content, $text );
+ }
}
}
return $text;
}
+ # always call this after unstrip() to preserve the order
+ function unstripNoWiki( $text, &$state ) {
+ # Must expand in reverse order, otherwise nested tags will be corrupted
+ for ( $content = end($state['nowiki']); $content !== false; $content = prev( $state['nowiki'] ) ) {
+ $text = str_replace( key( $state['nowiki'] ), $content, $text );
+ }
+
+ return $text;
+ }
# Add an item to the strip state
# Returns the unique tag which must be inserted into the stripped text
# The tag will be replaced with the original text in unstrip()
- function insertStripItem( $text, &$state )
- {
+ function insertStripItem( $text, &$state ) {
$rnd = UNIQ_PREFIX . '-item' . Parser::getRandomString();
if ( !$state ) {
$state = array(
'nowiki' => array(),
- 'hiero' => array(),
'math' => array(),
'pre' => array()
);
@@ -297,9 +323,24 @@ class Parser
return $rnd;
}
+ # categoryMagic
+ # generate a list of subcategories and pages for a category
+ # depending on wfMsg("usenewcategorypage") it either calls the new
+ # or the old code. The new code will not work properly for some
+ # languages due to sorting issues, so they might want to turn it
+ # off.
+ function categoryMagic() {
+ $msg = wfMsg('usenewcategorypage');
+ if ( '0' == @$msg[0] )
+ {
+ return $this->oldCategoryMagic();
+ } else {
+ return $this->newCategoryMagic();
+ }
+ }
+
# This method generates the list of subcategories and pages for a category
- function categoryMagic ()
- {
+ function oldCategoryMagic () {
global $wgLang , $wgUser ;
if ( !$this->mOptions->getUseCategoryMagic() ) return ; # Doesn't use categories at all
@@ -339,66 +380,247 @@ class Parser
# Showing subcategories
if ( count ( $children ) > 0 ) {
- $r .= "<h2>".wfMsg("subcategories")."</h2>\n" ;
- $r .= implode ( ", " , $children ) ;
+ $r .= '<h2>'.wfMsg('subcategories')."</h2>\n" ;
+ $r .= implode ( ', ' , $children ) ;
}
# Showing pages in this category
if ( count ( $articles ) > 0 ) {
$ti = $this->mTitle->getText() ;
- $h = wfMsg( "category_header", $ti );
+ $h = wfMsg( 'category_header', $ti );
$r .= "<h2>{$h}</h2>\n" ;
- $r .= implode ( ", " , $articles ) ;
+ $r .= implode ( ', ' , $articles ) ;
}
return $r ;
}
- function getHTMLattrs ()
- {
+
+
+ function newCategoryMagic () {
+ global $wgLang , $wgUser ;
+ if ( !$this->mOptions->getUseCategoryMagic() ) return ; # Doesn't use categories at all
+
+ $cns = Namespace::getCategory() ;
+ if ( $this->mTitle->getNamespace() != $cns ) return '' ; # This ain't a category page
+
+ $r = "<br style=\"clear:both;\"/>\n";
+
+
+ $sk =& $wgUser->getSkin() ;
+
+ $articles = array() ;
+ $articles_start_char = array();
+ $children = array() ;
+ $children_start_char = array();
+ $data = array () ;
+ $id = $this->mTitle->getArticleID() ;
+
+ # FIXME: add limits
+ $t = wfStrencode( $this->mTitle->getDBKey() );
+ $sql = "SELECT DISTINCT cur_title,cur_namespace,cl_sortkey FROM
+cur,categorylinks WHERE cl_to='$t' AND cl_from=cur_id ORDER BY
+cl_sortkey" ;
+ $res = wfQuery ( $sql, DB_READ ) ;
+ while ( $x = wfFetchObject ( $res ) )
+ {
+ $t = $ns = $wgLang->getNsText ( $x->cur_namespace ) ;
+ if ( $t != '' ) $t .= ':' ;
+ $t .= $x->cur_title ;
+
+ if ( $x->cur_namespace == $cns ) {
+ $ctitle = str_replace( '_',' ',$x->cur_title );
+ array_push ( $children, $sk->makeKnownLink ( $t, $ctitle ) ) ; # Subcategory
+
+ // If there's a link from Category:A to Category:B, the sortkey of the resulting
+ // entry in the categorylinks table is Category:A, not A, which it SHOULD be.
+ // Workaround: If sortkey == "Category:".$title, than use $title for sorting,
+ // else use sortkey...
+ if ( ($ns.":".$ctitle) == $x->cl_sortkey ) {
+ array_push ( $children_start_char, $wgLang->firstChar( $x->cur_title ) );
+ } else {
+ array_push ( $children_start_char, $wgLang->firstChar( $x->cl_sortkey ) ) ;
+ }
+ } else {
+ array_push ( $articles , $sk->makeLink ( $t ) ) ; # Page in this category
+ array_push ( $articles_start_char, $wgLang->firstChar( $x->cl_sortkey ) ) ;
+ }
+ }
+ wfFreeResult ( $res ) ;
+
+ $ti = $this->mTitle->getText() ;
+
+ # Don't show subcategories section if there are none.
+ if ( count ( $children ) > 0 )
+ {
+ # Showing subcategories
+ $r .= '<h2>' . wfMsg( 'subcategories' ) . "</h2>\n"
+ . wfMsg( 'subcategorycount', count( $children ) );
+ if ( count ( $children ) > 6 ) {
+
+ // divide list into three equal chunks
+ $chunk = (int) (count ( $children ) / 3);
+
+ // get and display header
+ $r .= '<table width="100%"><tr valign="top">';
+
+ $startChunk = 0;
+ $endChunk = $chunk;
+
+ // loop through the chunks
+ for($startChunk = 0, $endChunk = $chunk, $chunkIndex = 0;
+ $chunkIndex < 3;
+ $chunkIndex++, $startChunk = $endChunk, $endChunk += $chunk + 1)
+ {
+
+ $r .= '<td><ul>';
+ // output all subcategories to category
+ for ($index = $startChunk ;
+ $index < $endChunk && $index < count($children);
+ $index++ )
+ {
+ // check for change of starting letter or begging of chunk
+ if ( ($children_start_char[$index] != $children_start_char[$index - 1])
+ || ($index == $startChunk) )
+ {
+ $r .= "</ul><h3>{$children_start_char[$index]}</h3>\n<ul>";
+ }
+
+ $r .= "<li>{$children[$index]}</li>";
+ }
+ $r .= '</ul></td>';
+
+
+ }
+ $r .= '</tr></table>';
+ } else {
+ // for short lists of subcategories to category.
+
+ $r .= "<h3>{$children_start_char[0]}</h3>\n";
+ $r .= '<ul><li>'.$children[0].'</li>';
+ for ($index = 1; $index < count($children); $index++ )
+ {
+ if ($children_start_char[$index] != $children_start_char[$index - 1])
+ {
+ $r .= "</ul><h3>{$children_start_char[$index]}</h3>\n<ul>";
+ }
+
+ $r .= "<li>{$children[$index]}</li>";
+ }
+ $r .= '</ul>';
+ }
+ } # END of if ( count($children) > 0 )
+
+ $r .= '<h2>' . wfMsg( 'category_header', $ti ) . "</h2>\n" .
+ wfMsg( 'categoryarticlecount', count( $articles ) );
+
+ # Showing articles in this category
+ if ( count ( $articles ) > 6) {
+ $ti = $this->mTitle->getText() ;
+
+ // divide list into three equal chunks
+ $chunk = (int) (count ( $articles ) / 3);
+
+ // get and display header
+ $r .= '<table width="100%"><tr valign="top">';
+
+ // loop through the chunks
+ for($startChunk = 0, $endChunk = $chunk, $chunkIndex = 0;
+ $chunkIndex < 3;
+ $chunkIndex++, $startChunk = $endChunk, $endChunk += $chunk + 1)
+ {
+
+ $r .= '<td><ul>';
+
+ // output all articles in category
+ for ($index = $startChunk ;
+ $index < $endChunk && $index < count($articles);
+ $index++ )
+ {
+ // check for change of starting letter or begging of chunk
+ if ( ($articles_start_char[$index] != $articles_start_char[$index - 1])
+ || ($index == $startChunk) )
+ {
+ $r .= "</ul><h3>{$articles_start_char[$index]}</h3>\n<ul>";
+ }
+
+ $r .= "<li>{$articles[$index]}</li>";
+ }
+ $r .= '</ul></td>';
+
+
+ }
+ $r .= '</tr></table>';
+ } elseif ( count ( $articles ) > 0) {
+ // for short lists of articles in categories.
+ $ti = $this->mTitle->getText() ;
+
+ $r .= '<h3>'.$articles_start_char[0]."</h3>\n";
+ $r .= '<ul><li>'.$articles[0].'</li>';
+ for ($index = 1; $index < count($articles); $index++ )
+ {
+ if ($articles_start_char[$index] != $articles_start_char[$index - 1])
+ {
+ $r .= "</ul><h3>{$articles_start_char[$index]}</h3>\n<ul>";
+ }
+
+ $r .= "<li>{$articles[$index]}</li>";
+ }
+ $r .= '</ul>';
+ }
+
+
+ return $r ;
+ }
+
+ # Return allowed HTML attributes
+ function getHTMLattrs () {
$htmlattrs = array( # Allowed attributes--no scripting, etc.
- "title", "align", "lang", "dir", "width", "height",
- "bgcolor", "clear", /* BR */ "noshade", /* HR */
- "cite", /* BLOCKQUOTE, Q */ "size", "face", "color",
- /* FONT */ "type", "start", "value", "compact",
+ 'title', 'align', 'lang', 'dir', 'width', 'height',
+ 'bgcolor', 'clear', /* BR */ 'noshade', /* HR */
+ 'cite', /* BLOCKQUOTE, Q */ 'size', 'face', 'color',
+ /* FONT */ 'type', 'start', 'value', 'compact',
/* For various lists, mostly deprecated but safe */
- "summary", "width", "border", "frame", "rules",
- "cellspacing", "cellpadding", "valign", "char",
- "charoff", "colgroup", "col", "span", "abbr", "axis",
- "headers", "scope", "rowspan", "colspan", /* Tables */
- "id", "class", "name", "style" /* For CSS */
+ 'summary', 'width', 'border', 'frame', 'rules',
+ 'cellspacing', 'cellpadding', 'valign', 'char',
+ 'charoff', 'colgroup', 'col', 'span', 'abbr', 'axis',
+ 'headers', 'scope', 'rowspan', 'colspan', /* Tables */
+ 'id', 'class', 'name', 'style' /* For CSS */
);
return $htmlattrs ;
}
- function fixTagAttributes ( $t )
- {
- if ( trim ( $t ) == "" ) return "" ; # Saves runtime ;-)
+ # Remove non approved attributes and javascript in css
+ function fixTagAttributes ( $t ) {
+ if ( trim ( $t ) == '' ) return '' ; # Saves runtime ;-)
$htmlattrs = $this->getHTMLattrs() ;
# Strip non-approved attributes from the tag
$t = preg_replace(
- "/(\\w+)(\\s*=\\s*([^\\s\">]+|\"[^\">]*\"))?/e",
+ '/(\\w+)(\\s*=\\s*([^\\s\">]+|\"[^\">]*\"))?/e',
"(in_array(strtolower(\"\$1\"),\$htmlattrs)?(\"\$1\".((\"x\$3\" != \"x\")?\"=\$3\":'')):'')",
$t);
# Strip javascript "expression" from stylesheets. Brute force approach:
# If anythin offensive is found, all attributes of the HTML tag are dropped
if( preg_match(
- "/style\\s*=.*(expression|tps*:\/\/|url\\s*\().*/is",
+ '/style\\s*=.*(expression|tps*:\/\/|url\\s*\().*/is',
wfMungeToUtf8( $t ) ) )
{
- $t="";
+ $t='';
}
return trim ( $t ) ;
}
- /* interface with html tidy, used if $wgUseTidy = true */
+ # interface with html tidy, used if $wgUseTidy = true
function tidy ( $text ) {
global $wgTidyConf, $wgTidyBin, $wgTidyOpts;
global $wgInputEncoding, $wgOutputEncoding;
+ $fname = 'Parser::tidy';
+ wfProfileIn( $fname );
+
$cleansource = '';
switch(strtoupper($wgOutputEncoding)) {
case 'ISO-8859-1':
@@ -411,17 +633,17 @@ class Parser
$wgTidyOpts .= ' -raw';
}
- $text = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'.
+ $wrappedtext = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'.
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>'.
'<head><title>test</title></head><body>'.$text.'</body></html>';
$descriptorspec = array(
- 0 => array("pipe", "r"),
- 1 => array("pipe", "w"),
- 2 => array("file", "/dev/null", "a")
+ 0 => array('pipe', 'r'),
+ 1 => array('pipe', 'w'),
+ 2 => array('file', '/dev/null', 'a')
);
$process = proc_open("$wgTidyBin -config $wgTidyConf $wgTidyOpts", $descriptorspec, $pipes);
if (is_resource($process)) {
- fwrite($pipes[0], $text);
+ fwrite($pipes[0], $wrappedtext);
fclose($pipes[0]);
while (!feof($pipes[1])) {
$cleansource .= fgets($pipes[1], 1024);
@@ -429,15 +651,19 @@ class Parser
fclose($pipes[1]);
$return_value = proc_close($process);
}
+
+ wfProfileOut( $fname );
+
if( $cleansource == '' && $text != '') {
- return '<h2>'.wfMsg('seriousxhtmlerrors').'</h2><pre>'.htmlspecialchars($text).'</pre>';
+ wfDebug( "Tidy error detected!\n" );
+ return $text . "\n<!-- Tidy found serious XHTML errors -->\n";
} else {
return $cleansource;
}
}
- function doTableStuff ( $t )
- {
+ # parse the wiki syntax used to render tables
+ function doTableStuff ( $t ) {
$t = explode ( "\n" , $t ) ;
$td = array () ; # Is currently a td tag open?
$ltd = array () ; # Was it TD or TH?
@@ -447,20 +673,20 @@ class Parser
{
$x = trim ( $x ) ;
$fc = substr ( $x , 0 , 1 ) ;
- if ( "{|" == substr ( $x , 0 , 2 ) )
+ if ( '{|' == substr ( $x , 0 , 2 ) )
{
- $t[$k] = "\n<table " . $this->fixTagAttributes ( substr ( $x , 3 ) ) . ">" ;
+ $t[$k] = "\n<table " . $this->fixTagAttributes ( substr ( $x , 3 ) ) . '>' ;
array_push ( $td , false ) ;
- array_push ( $ltd , "" ) ;
+ array_push ( $ltd , '' ) ;
array_push ( $tr , false ) ;
- array_push ( $ltr , "" ) ;
+ array_push ( $ltr , '' ) ;
}
else if ( count ( $td ) == 0 ) { } # Don't do any of the following
- else if ( "|}" == substr ( $x , 0 , 2 ) )
+ else if ( '|}' == substr ( $x , 0 , 2 ) )
{
$z = "</table>\n" ;
$l = array_pop ( $ltd ) ;
- if ( array_pop ( $tr ) ) $z = "</tr>" . $z ;
+ if ( array_pop ( $tr ) ) $z = '</tr>' . $z ;
if ( array_pop ( $td ) ) $z = "</{$l}>" . $z ;
array_pop ( $ltr ) ;
$t[$k] = $z ;
@@ -470,51 +696,51 @@ class Parser
$z = trim ( substr ( $x , 2 ) ) ;
$t[$k] = "<caption>{$z}</caption>\n" ;
}*/
- else if ( "|-" == substr ( $x , 0 , 2 ) ) # Allows for |---------------
+ else if ( '|-' == substr ( $x , 0 , 2 ) ) # Allows for |---------------
{
$x = substr ( $x , 1 ) ;
- while ( $x != "" && substr ( $x , 0 , 1 ) == '-' ) $x = substr ( $x , 1 ) ;
- $z = "" ;
+ while ( $x != '' && substr ( $x , 0 , 1 ) == '-' ) $x = substr ( $x , 1 ) ;
+ $z = '' ;
$l = array_pop ( $ltd ) ;
- if ( array_pop ( $tr ) ) $z = "</tr>" . $z ;
+ if ( array_pop ( $tr ) ) $z = '</tr>' . $z ;
if ( array_pop ( $td ) ) $z = "</{$l}>" . $z ;
array_pop ( $ltr ) ;
$t[$k] = $z ;
array_push ( $tr , false ) ;
array_push ( $td , false ) ;
- array_push ( $ltd , "" ) ;
+ array_push ( $ltd , '' ) ;
array_push ( $ltr , $this->fixTagAttributes ( $x ) ) ;
}
- else if ( "|" == $fc || "!" == $fc || "|+" == substr ( $x , 0 , 2 ) ) # Caption
+ else if ( '|' == $fc || '!' == $fc || '|+' == substr ( $x , 0 , 2 ) ) # Caption
{
- if ( "|+" == substr ( $x , 0 , 2 ) )
+ if ( '|+' == substr ( $x , 0 , 2 ) )
{
- $fc = "+" ;
+ $fc = '+' ;
$x = substr ( $x , 1 ) ;
}
$after = substr ( $x , 1 ) ;
- if ( $fc == "!" ) $after = str_replace ( "!!" , "||" , $after ) ;
- $after = explode ( "||" , $after ) ;
- $t[$k] = "" ;
+ if ( $fc == '!' ) $after = str_replace ( '!!' , '||' , $after ) ;
+ $after = explode ( '||' , $after ) ;
+ $t[$k] = '' ;
foreach ( $after AS $theline )
{
- $z = "" ;
- if ( $fc != "+" )
+ $z = '' ;
+ if ( $fc != '+' )
{
$tra = array_pop ( $ltr ) ;
if ( !array_pop ( $tr ) ) $z = "<tr {$tra}>\n" ;
array_push ( $tr , true ) ;
- array_push ( $ltr , "" ) ;
+ array_push ( $ltr , '' ) ;
}
$l = array_pop ( $ltd ) ;
if ( array_pop ( $td ) ) $z = "</{$l}>" . $z ;
- if ( $fc == "|" ) $l = "td" ;
- else if ( $fc == "!" ) $l = "th" ;
- else if ( $fc == "+" ) $l = "caption" ;
- else $l = "" ;
+ if ( $fc == '|' ) $l = 'td' ;
+ else if ( $fc == '!' ) $l = 'th' ;
+ else if ( $fc == '+' ) $l = 'caption' ;
+ else $l = '' ;
array_push ( $ltd , $l ) ;
- $y = explode ( "|" , $theline , 2 ) ;
+ $y = explode ( '|' , $theline , 2 ) ;
if ( count ( $y ) == 1 ) $y = "{$z}<{$l}>{$y[0]}" ;
else $y = $y = "{$z}<{$l} ".$this->fixTagAttributes($y[0]).">{$y[1]}" ;
$t[$k] .= $y ;
@@ -526,9 +752,9 @@ class Parser
# Closing open td, tr && table
while ( count ( $td ) > 0 )
{
- if ( array_pop ( $td ) ) $t[] = "</td>" ;
- if ( array_pop ( $tr ) ) $t[] = "</tr>" ;
- $t[] = "</table>" ;
+ if ( array_pop ( $td ) ) $t[] = '</td>' ;
+ if ( array_pop ( $tr ) ) $t[] = '</tr>' ;
+ $t[] = '</table>' ;
}
$t = implode ( "\n" , $t ) ;
@@ -536,24 +762,38 @@ class Parser
return $t ;
}
- function internalParse( $text, $linestart, $args = array(), $isMain=true )
+ # Parses the text and adds the result to the strip state
+ # Returns the strip tag
+ function stripParse( $text, $newline, $args )
{
- $fname = "Parser::internalParse";
+ $text = $this->strip( $text, $this->mStripState );
+ $text = $this->internalParse( $text, (bool)$newline, $args, false );
+ return $newline.$this->insertStripItem( $text, $this->mStripState );
+ }
+
+ function internalParse( $text, $linestart, $args = array(), $isMain=true ) {
+ $fname = 'Parser::internalParse';
wfProfileIn( $fname );
$text = $this->removeHTMLtags( $text );
$text = $this->replaceVariables( $text, $args );
- # $text = preg_replace( "/(^|\n)-----*/", "\\1<hr>", $text );
+ $text = preg_replace( '/(^|\n)-----*/', '\\1<hr />', $text );
$text = $this->doHeadings( $text );
if($this->mOptions->getUseDynamicDates()) {
global $wgDateFormatter;
$text = $wgDateFormatter->reformat( $this->mOptions->getDateFormat(), $text );
}
+ $text = $this->doAllQuotes( $text );
+ // $text = $this->doExponent( $text );
$text = $this->replaceExternalLinks( $text );
- $text = $this->doTokenizedParser ( $text );
+ $text = $this->replaceInternalLinks ( $text );
+ $text = $this->replaceInternalLinks ( $text );
+ //$text = $this->doTokenizedParser ( $text );
$text = $this->doTableStuff ( $text ) ;
+ $text = $this->magicISBN( $text );
+ $text = $this->magicRFC( $text );
$text = $this->formatHeadings( $text, $isMain );
$sk =& $this->mOptions->getSkin();
$text = $sk->transformContent( $text );
@@ -566,40 +806,110 @@ class Parser
wfProfileOut( $fname );
return $text;
}
-
-
- /* private */ function doHeadings( $text )
+
+ # Parse ^^ tokens and return html
+ /* private */ function doExponent ( $text )
{
+ $fname = 'Parser::doExponent';
+ wfProfileIn( $fname);
+ $text = preg_replace('/\^\^(.*)\^\^/','<small><sup>\\1</sup></small>', $text);
+ wfProfileOut( $fname);
+ return $text;
+ }
+
+ # Parse headers and return html
+ /* private */ function doHeadings( $text ) {
+ $fname = 'Parser::doHeadings';
+ wfProfileIn( $fname );
for ( $i = 6; $i >= 1; --$i ) {
- $h = substr( "======", 0, $i );
+ $h = substr( '======', 0, $i );
$text = preg_replace( "/^{$h}(.+){$h}(\\s|$)/m",
"<h{$i}>\\1</h{$i}>\\2", $text );
}
+ wfProfileOut( $fname );
return $text;
}
+ /* private */ function doAllQuotes( $text ) {
+ $fname = 'Parser::doAllQuotes';
+ wfProfileIn( $fname );
+ $outtext = '';
+ $lines = explode( "\n", $text );
+ foreach ( $lines as $line ) {
+ $outtext .= $this->doQuotes ( '', $line, '' ) . "\n";
+ }
+ $outtext = substr($outtext, 0,-1);
+ wfProfileOut( $fname );
+ return $outtext;
+ }
+
+ /* private */ function doQuotes( $pre, $text, $mode ) {
+ if ( preg_match( "/^(.*)''(.*)$/sU", $text, $m ) ) {
+ $m1_strong = ($m[1] == "") ? "" : "<strong>{$m[1]}</strong>";
+ $m1_em = ($m[1] == "") ? "" : "<em>{$m[1]}</em>";
+ if ( substr ($m[2], 0, 1) == '\'' ) {
+ $m[2] = substr ($m[2], 1);
+ if ($mode == 'em') {
+ return $this->doQuotes ( $m[1], $m[2], ($m[1] == '') ? 'both' : 'emstrong' );
+ } else if ($mode == 'strong') {
+ return $m1_strong . $this->doQuotes ( '', $m[2], '' );
+ } else if (($mode == 'emstrong') || ($mode == 'both')) {
+ return $this->doQuotes ( '', $pre.$m1_strong.$m[2], 'em' );
+ } else if ($mode == 'strongem') {
+ return "<strong>{$pre}{$m1_em}</strong>" . $this->doQuotes ( '', $m[2], 'em' );
+ } else {
+ return $m[1] . $this->doQuotes ( '', $m[2], 'strong' );
+ }
+ } else {
+ if ($mode == 'strong') {
+ return $this->doQuotes ( $m[1], $m[2], ($m[1] == '') ? 'both' : 'strongem' );
+ } else if ($mode == 'em') {
+ return $m1_em . $this->doQuotes ( '', $m[2], '' );
+ } else if ($mode == 'emstrong') {
+ return "<em>{$pre}{$m1_strong}</em>" . $this->doQuotes ( '', $m[2], 'strong' );
+ } else if (($mode == 'strongem') || ($mode == 'both')) {
+ return $this->doQuotes ( '', $pre.$m1_em.$m[2], 'strong' );
+ } else {
+ return $m[1] . $this->doQuotes ( '', $m[2], 'em' );
+ }
+ }
+ } else {
+ $text_strong = ($text == '') ? '' : "<strong>{$text}</strong>";
+ $text_em = ($text == '') ? '' : "<em>{$text}</em>";
+ if ($mode == '') {
+ return $pre . $text;
+ } else if ($mode == 'em') {
+ return $pre . $text_em;
+ } else if ($mode == 'strong') {
+ return $pre . $text_strong;
+ } else if ($mode == 'strongem') {
+ return (($pre == '') && ($text == '')) ? '' : "<strong>{$pre}{$text_em}</strong>";
+ } else {
+ return (($pre == '') && ($text == '')) ? '' : "<em>{$pre}{$text_strong}</em>";
+ }
+ }
+ }
+
# Note: we have to do external links before the internal ones,
# and otherwise take great care in the order of things here, so
# that we don't end up interpreting some URLs twice.
- /* private */ function replaceExternalLinks( $text )
- {
- $fname = "Parser::replaceExternalLinks";
+ /* private */ function replaceExternalLinks( $text ) {
+ $fname = 'Parser::replaceExternalLinks';
wfProfileIn( $fname );
- $text = $this->subReplaceExternalLinks( $text, "http", true );
- $text = $this->subReplaceExternalLinks( $text, "https", true );
- $text = $this->subReplaceExternalLinks( $text, "ftp", false );
- $text = $this->subReplaceExternalLinks( $text, "irc", false );
- $text = $this->subReplaceExternalLinks( $text, "gopher", false );
- $text = $this->subReplaceExternalLinks( $text, "news", false );
- $text = $this->subReplaceExternalLinks( $text, "mailto", false );
+ $text = $this->subReplaceExternalLinks( $text, 'http', true );
+ $text = $this->subReplaceExternalLinks( $text, 'https', true );
+ $text = $this->subReplaceExternalLinks( $text, 'ftp', false );
+ $text = $this->subReplaceExternalLinks( $text, 'irc', false );
+ $text = $this->subReplaceExternalLinks( $text, 'gopher', false );
+ $text = $this->subReplaceExternalLinks( $text, 'news', false );
+ $text = $this->subReplaceExternalLinks( $text, 'mailto', false );
wfProfileOut( $fname );
return $text;
}
- /* private */ function subReplaceExternalLinks( $s, $protocol, $autonumber )
- {
- $unique = "4jzAfzB8hNvf4sqyO9Edd8pSmk9rE2in0Tgw3";
+ /* private */ function subReplaceExternalLinks( $s, $protocol, $autonumber ) {
+ $unique = '4jzAfzB8hNvf4sqyO9Edd8pSmk9rE2in0Tgw3';
$uc = "A-Za-z0-9_\\/~%\\-+&*#?!=()@\\x80-\\xFF";
# this is the list of separators that should be ignored if they
@@ -608,8 +918,8 @@ class Parser
# in this case, the last comma should not become part of the URL,
# but in "www.foo.com/123,2342,32.htm" it should.
$sep = ",;\.:";
- $fnc = "A-Za-z0-9_.,~%\\-+&;#*?!=()@\\x80-\\xFF";
- $images = "gif|png|jpg|jpeg";
+ $fnc = 'A-Za-z0-9_.,~%\\-+&;#*?!=()@\\x80-\\xFF';
+ $images = 'gif|png|jpg|jpeg';
# PLEASE NOTE: The curly braces { } are not part of the regex,
# they are interpreted as part of the string (used to tell PHP
@@ -621,13 +931,13 @@ class Parser
$sk =& $this->mOptions->getSkin();
if ( $autonumber and $this->mOptions->getAllowExternalImages() ) { # Use img tags only for HTTP urls
- $s = preg_replace( $e1, "\\1" . $sk->makeImage( "{$unique}:\\3" .
- "/\\4.\\5", "\\4.\\5" ) . "\\6", $s );
+ $s = preg_replace( $e1, '\\1' . $sk->makeImage( "{$unique}:\\3" .
+ '/\\4.\\5', '\\4.\\5' ) . '\\6', $s );
}
- $s = preg_replace( $e2, "\\1" . "<a href=\"{$unique}:\\3\"" .
+ $s = preg_replace( $e2, '\\1' . "<a href=\"{$unique}:\\3\"" .
$sk->getExternalLinkAttributes( "{$unique}:\\3", wfEscapeHTML(
"{$unique}:\\3" ) ) . ">" . wfEscapeHTML( "{$unique}:\\3" ) .
- "</a>\\5", $s );
+ '</a>\\5', $s );
$s = str_replace( $unique, $protocol, $s );
$a = explode( "[{$protocol}:", " " . $s );
@@ -652,7 +962,7 @@ class Parser
continue;
}
if( $link == $text || preg_match( "!$protocol://" . preg_quote( $text, "/" ) . "/?$!", $link ) ) {
- $paren = "";
+ $paren = '';
} else {
# Expand the URL for printable version
$paren = "<span class='urlexpansion'> (<i>" . htmlspecialchars ( $link ) . "</i>)</span>";
@@ -664,301 +974,31 @@ class Parser
return $s;
}
- /* private */ function handle4Quotes( &$state, $token )
- {
- /* This one makes some assumptions.
- * '''Caesar''''s army => <strong>Caesar</strong>'s army
- * ''''Caesar'''' was a roman emperor => '<strong>Caesar</strong>' was a roman emperor
- * These assumptions might be wrong, but any other assumption might be wrong, too.
- * So here we go */
- if ( $state["strong"] !== false ) {
- return $this->handle3Quotes( $state, $token ) . "'";
- } else {
- return "'" . $this->handle3Quotes( $state, $token );
- }
- }
-
-
- /* private */ function handle3Quotes( &$state, $token )
- {
- if ( $state["strong"] !== false ) {
- if ( $state["em"] !== false && $state["em"] > $state["strong"] )
- {
- # ''' lala ''lala '''
- $s = "</em></strong><em>";
- } else {
- $s = "</strong>";
- }
- $state["strong"] = FALSE;
- } else {
- $s = "<strong>";
- $state["strong"] = $token["pos"];
- }
- return $s;
- }
-
- /* private */ function handle2Quotes( &$state, $token )
- {
- if ( $state["em"] !== false ) {
- if ( $state["strong"] !== false && $state["strong"] > $state["em"] )
- {
- # ''lala'''lala'' ....'''
- $s = "</strong></em><strong>";
- } else {
- $s = "</em>";
- }
- $state["em"] = FALSE;
- } else {
- $s = "<em>";
- $state["em"] = $token["pos"];
-
- }
- return $s;
- }
-
- /* private */ function handle5Quotes( &$state, $token )
- {
- $s = "";
- if ( $state["em"] !== false && $state["strong"] !== false ) {
- if ( $state["em"] < $state["strong"] ) {
- $s .= "</strong></em>";
- } else {
- $s .= "</em></strong>";
- }
- $state["strong"] = $state["em"] = FALSE;
- } elseif ( $state["em"] !== false ) {
- $s .= "</em><strong>";
- $state["em"] = FALSE;
- $state["strong"] = $token["pos"];
- } elseif ( $state["strong"] !== false ) {
- $s .= "</strong><em>";
- $state["strong"] = FALSE;
- $state["em"] = $token["pos"];
- } else { # not $em and not $strong
- $s .= "<strong><em>";
- $state["strong"] = $state["em"] = $token["pos"];
- }
- return $s;
- }
-
- /* private */ function doTokenizedParser( $str )
- {
- global $wgLang; # for language specific parser hook
- global $wgUploadDirectory, $wgUseTimeline;
-
- $tokenizer=Tokenizer::newFromString( $str );
- $tokenStack = array();
-
- $s="";
- $state["em"] = FALSE;
- $state["strong"] = FALSE;
- $tagIsOpen = FALSE;
- $threeopen = false;
-
- # The tokenizer splits the text into tokens and returns them one by one.
- # Every call to the tokenizer returns a new token.
- while ( $token = $tokenizer->nextToken() )
- {
- switch ( $token["type"] )
- {
- case "text":
- # simple text with no further markup
- $txt = $token["text"];
- break;
- case "blank":
- # Text that contains blanks that have to be converted to
- # non-breakable spaces for French.
- # U+202F NARROW NO-BREAK SPACE might be a better choice, but
- # browser support for Unicode spacing is poor.
- $txt = str_replace( " ", "&nbsp;", $token["text"] );
- break;
- case "[[[":
- # remember the tag opened with 3 [
- $threeopen = true;
- case "[[":
- # link opening tag.
- # FIXME : Treat orphaned open tags (stack not empty when text is over)
- $tagIsOpen = TRUE;
- array_push( $tokenStack, $token );
- $txt="";
- break;
-
- case "]]]":
- case "]]":
- # link close tag.
- # get text from stack, glue it together, and call the code to handle a
- # link
-
- if ( count( $tokenStack ) == 0 )
- {
- # stack empty. Found a ]] without an opening [[
- $txt = "]]";
- } else {
- $linkText = "";
- $lastToken = array_pop( $tokenStack );
- while ( !(($lastToken["type"] == "[[[") or ($lastToken["type"] == "[[")) )
- {
- if( !empty( $lastToken["text"] ) ) {
- $linkText = $lastToken["text"] . $linkText;
- }
- $lastToken = array_pop( $tokenStack );
- }
-
- $txt = $linkText ."]]";
- if( isset( $lastToken["text"] ) ) {
- $prefix = $lastToken["text"];
- } else {
- $prefix = "";
- }
- $nextToken = $tokenizer->previewToken();
- if ( $nextToken["type"] == "text" )
- {
- # Preview just looks at it. Now we have to fetch it.
- $nextToken = $tokenizer->nextToken();
- $txt .= $nextToken["text"];
- }
- $txt = $this->handleInternalLink( $this->unstrip($txt,$this->mStripState), $prefix );
-
- # did the tag start with 3 [ ?
- if($threeopen) {
- # show the first as text
- $txt = "[".$txt;
- $threeopen=false;
- }
-
- }
- $tagIsOpen = (count( $tokenStack ) != 0);
- break;
- case "----":
- $txt = "\n<hr />\n";
- break;
- case "'''":
- # This and the four next ones handle quotes
- $txt = $this->handle3Quotes( $state, $token );
- break;
- case "''":
- $txt = $this->handle2Quotes( $state, $token );
- break;
- case "'''''":
- $txt = $this->handle5Quotes( $state, $token );
- break;
- case "''''":
- $txt = $this->handle4Quotes( $state, $token );
- break;
- case "":
- # empty token
- $txt="";
- break;
- case "h":
- #heading- used to close all unbalanced bold or em tags in this section
- $txt = '';
- if( $state['em'] !== false and
- ( $state['strong'] === false or $state['em'] > $state['strong'] ) )
- {
- $s .= '</em>';
- $state['em'] = false;
- }
- if ( $state['strong'] !== false ) $txt .= '</strong>';
- if ( $state['em'] !== false ) $txt .= '</em>';
- $state['strong'] = $state['em'] = false;
- break;
- case "RFC ":
- if ( $tagIsOpen ) {
- $txt = "RFC ";
- } else {
- $txt = $this->doMagicRFC( $tokenizer );
- }
- break;
- case "ISBN ":
- if ( $tagIsOpen ) {
- $txt = "ISBN ";
- } else {
- $txt = $this->doMagicISBN( $tokenizer );
- }
- break;
- case "<timeline>":
- if ( $wgUseTimeline &&
- "" != ( $timelinesrc = $tokenizer->readAllUntil("&lt;/timeline&gt;") ) )
- {
- $txt = renderTimeline( $timelinesrc );
- } else {
- $txt=$token["text"];
- }
- break;
- default:
- # Call language specific Hook.
- $txt = $wgLang->processToken( $token, $tokenStack );
- if ( NULL == $txt ) {
- # An unkown token. Highlight.
- $txt = "<font color=\"#FF0000\"><b>".$token["type"]."</b></font>";
- $txt .= "<font color=\"#FFFF00\"><b>".$token["text"]."</b></font>";
- }
- break;
- }
- # If we're parsing the interior of a link, don't append the interior to $s,
- # but push it to the stack so it can be processed when a ]] token is found.
- if ( $tagIsOpen && $txt != "" ) {
- $token["type"] = "text";
- $token["text"] = $txt;
- array_push( $tokenStack, $token );
- } else {
- $s .= $txt;
- }
- } #end while
-
- # make 100% sure all strong and em tags are closed
- # doBlockLevels often messes the last bit up though, but invalid nesting is better than unclosed tags
- # tidy solves this though
- if( $state['em'] !== false and
- ( $state['strong'] === false or $state['em'] > $state['strong'] ) )
- {
- $s .= '</em>';
- $state['em'] = false;
- }
- if ( $state['strong'] !== false ) $s .= '</strong>';
- if ( $state['em'] !== false ) $s .= '</em>';
-
- if ( count( $tokenStack ) != 0 )
- {
- # still objects on stack. opened [[ tag without closing ]] tag.
- $txt = "";
- while ( $lastToken = array_pop( $tokenStack ) )
- {
- if ( $lastToken["type"] == "text" )
- {
- $txt = $lastToken["text"] . $txt;
- } else {
- $txt = $lastToken["type"] . $txt;
- }
- }
- $s .= $txt;
- }
- return $s;
- }
-
- /* private */ function handleInternalLink( $line, $prefix )
- {
+ /* private */ function replaceInternalLinks( $s ) {
global $wgLang, $wgLinkCache;
global $wgNamespacesWithSubpages, $wgLanguageCode;
- static $fname = "Parser::handleInternalLink" ;
+ static $fname = 'Parser::replaceInternalLinks' ;
wfProfileIn( $fname );
- wfProfileIn( "$fname-setup" );
+ wfProfileIn( $fname.'-setup' );
static $tc = FALSE;
- if ( !$tc ) { $tc = Title::legalChars() . "#"; }
+ # the % is needed to support urlencoded titles as well
+ if ( !$tc ) { $tc = Title::legalChars() . '#%'; }
$sk =& $this->mOptions->getSkin();
+ $a = explode( '[[', ' ' . $s );
+ $s = array_shift( $a );
+ $s = substr( $s, 1 );
+
# Match a link having the form [[namespace:link|alternate]]trail
static $e1 = FALSE;
if ( !$e1 ) { $e1 = "/^([{$tc}]+)(?:\\|([^]]+))?]](.*)\$/sD"; }
# Match the end of a line for a word that's not followed by whitespace,
# e.g. in the case of 'The Arab al[[Razi]]', 'al' will be matched
- #$e2 = "/^(.*)\\b(\\w+)\$/suD";
- #$e2 = "/^(.*\\s)(\\S+)\$/suD";
- static $e2 = '/^(.*\s)([a-zA-Z\x80-\xff]+)$/sD';
-
+ static $e2 = '/^(.*?)([a-zA-Z\x80-\xff]+)$/sD';
+ $useLinkPrefixExtension = $wgLang->linkPrefixExtension();
# Special and Media are pseudo-namespaces; no pages actually exist in them
static $image = FALSE;
static $special = FALSE;
@@ -971,120 +1011,148 @@ class Parser
$nottalk = !Namespace::isTalk( $this->mTitle->getNamespace() );
- wfProfileOut( "$fname-setup" );
- $s = "";
-
- if ( preg_match( $e1, $line, $m ) ) { # page with normal text or alt
- $text = $m[2];
- $trail = $m[3];
- } else { # Invalid form; output directly
- $s .= $prefix . "[[" . $line ;
- return $s;
+ if ( $useLinkPrefixExtension ) {
+ if ( preg_match( $e2, $s, $m ) ) {
+ $first_prefix = $m[2];
+ $s = $m[1];
+ } else {
+ $first_prefix = false;
+ }
+ } else {
+ $prefix = '';
}
- /* Valid link forms:
- Foobar -- normal
- :Foobar -- override special treatment of prefix (images, language links)
- /Foobar -- convert to CurrentPage/Foobar
- /Foobar/ -- convert to CurrentPage/Foobar, strip the initial / from text
- */
- $c = substr($m[1],0,1);
- $noforce = ($c != ":");
- if( $c == "/" ) { # subpage
- if(substr($m[1],-1,1)=="/") { # / at end means we don't want the slash to be shown
- $m[1]=substr($m[1],1,strlen($m[1])-2);
- $noslash=$m[1];
- } else {
- $noslash=substr($m[1],1);
+ wfProfileOut( $fname.'-setup' );
+
+ foreach ( $a as $line ) {
+ wfProfileIn( $fname.'-prefixhandling' );
+ if ( $useLinkPrefixExtension ) {
+ if ( preg_match( $e2, $s, $m ) ) {
+ $prefix = $m[2];
+ $s = $m[1];
+ } else {
+ $prefix='';
+ }
+ # first link
+ if($first_prefix) {
+ $prefix = $first_prefix;
+ $first_prefix = false;
+ }
}
- if($wgNamespacesWithSubpages[$this->mTitle->getNamespace()]) { # subpages allowed here
- $link = $this->mTitle->getPrefixedText(). "/" . trim($noslash);
- if( "" == $text ) {
- $text= $m[1];
- } # this might be changed for ugliness reasons
+ wfProfileOut( $fname.'-prefixhandling' );
+
+ if ( preg_match( $e1, $line, $m ) ) { # page with normal text or alt
+ $text = $m[2];
+ # fix up urlencoded title texts
+ if(preg_match('/%/', $m[1] )) $m[1] = urldecode($m[1]);
+ $trail = $m[3];
+ } else { # Invalid form; output directly
+ $s .= $prefix . '[[' . $line ;
+ continue;
+ }
+
+ /* Valid link forms:
+ Foobar -- normal
+ :Foobar -- override special treatment of prefix (images, language links)
+ /Foobar -- convert to CurrentPage/Foobar
+ /Foobar/ -- convert to CurrentPage/Foobar, strip the initial / from text
+ */
+ $c = substr($m[1],0,1);
+ $noforce = ($c != ':');
+ if( $c == '/' ) { # subpage
+ if(substr($m[1],-1,1)=='/') { # / at end means we don't want the slash to be shown
+ $m[1]=substr($m[1],1,strlen($m[1])-2);
+ $noslash=$m[1];
+ } else {
+ $noslash=substr($m[1],1);
+ }
+ if(!empty($wgNamespacesWithSubpages[$this->mTitle->getNamespace()])) { # subpages allowed here
+ $link = $this->mTitle->getPrefixedText(). '/' . trim($noslash);
+ if( '' == $text ) {
+ $text= $m[1];
+ } # this might be changed for ugliness reasons
+ } else {
+ $link = $noslash; # no subpage allowed, use standard link
+ }
+ } elseif( $noforce ) { # no subpage
+ $link = $m[1];
} else {
- $link = $noslash; # no subpage allowed, use standard link
+ $link = substr( $m[1], 1 );
}
- } elseif( $noforce ) { # no subpage
- $link = $m[1];
- } else {
- $link = substr( $m[1], 1 );
- }
- $wasblank = ( "" == $text );
- if( $wasblank )
+ $wasblank = ( '' == $text );
+ if( $wasblank )
$text = $link;
- $nt = Title::newFromText( $link );
- if( !$nt ) {
- $s .= $prefix . "[[" . $line;
- return $s;
- }
- $ns = $nt->getNamespace();
- $iw = $nt->getInterWiki();
- if( $noforce ) {
- if( $iw && $this->mOptions->getInterwikiMagic() && $nottalk && $wgLang->getLanguageName( $iw ) ) {
- array_push( $this->mOutput->mLanguageLinks, $nt->getPrefixedText() );
- $s .= $prefix . $trail ;
- return (trim($s) == '')? '': $s;
- }
- if( $ns == $image ) {
- $s .= $prefix . $sk->makeImageLinkObj( $nt, $text ) . $trail;
- $wgLinkCache->addImageLinkObj( $nt );
- return $s;
+ $nt = Title::newFromText( $link );
+ if( !$nt ) {
+ $s .= $prefix . '[[' . $line;
+ continue;
}
- if ( $ns == $category ) {
- $t = $nt->getText() ;
- $nnt = Title::newFromText ( Namespace::getCanonicalName($category).":".$t ) ;
-
- $wgLinkCache->suspend(); # Don't save in links/brokenlinks
- $t = $sk->makeLinkObj( $nnt, $t, "", "" , $prefix );
- $wgLinkCache->resume();
-
- $sortkey = $wasblank ? $this->mTitle->getPrefixedText() : $text;
- $wgLinkCache->addCategoryLinkObj( $nt, $sortkey );
- $this->mOutput->mCategoryLinks[] = $t ;
- $s .= $prefix . $trail ;
- return $s ;
+ $ns = $nt->getNamespace();
+ $iw = $nt->getInterWiki();
+ if( $noforce ) {
+ if( $iw && $this->mOptions->getInterwikiMagic() && $nottalk && $wgLang->getLanguageName( $iw ) ) {
+ array_push( $this->mOutput->mLanguageLinks, $nt->getPrefixedText() );
+ $tmp = $prefix . $trail ;
+ $s .= (trim($tmp) == '')? '': $tmp;
+ continue;
+ }
+ if ( $ns == $image ) {
+ $s .= $prefix . $sk->makeImageLinkObj( $nt, $text ) . $trail;
+ $wgLinkCache->addImageLinkObj( $nt );
+ continue;
+ }
+ if ( $ns == $category ) {
+ $t = $nt->getText() ;
+ $nnt = Title::newFromText ( Namespace::getCanonicalName($category).":".$t ) ;
+
+ $wgLinkCache->suspend(); # Don't save in links/brokenlinks
+ $t = $sk->makeLinkObj( $nnt, $t, '', '' , $prefix );
+ $wgLinkCache->resume();
+
+ $sortkey = $wasblank ? $this->mTitle->getPrefixedText() : $text;
+ $wgLinkCache->addCategoryLinkObj( $nt, $sortkey );
+ $this->mOutput->mCategoryLinks[] = $t ;
+ $s .= $prefix . $trail ;
+ continue;
+ }
+ }
+ if( ( $nt->getPrefixedText() == $this->mTitle->getPrefixedText() ) &&
+ ( strpos( $link, '#' ) == FALSE ) ) {
+ # Self-links are handled specially; generally de-link and change to bold.
+ $s .= $prefix . $sk->makeSelfLinkObj( $nt, $text, '', $trail );
+ continue;
}
- }
- if( ( $nt->getPrefixedText() == $this->mTitle->getPrefixedText() ) &&
- ( strpos( $link, "#" ) == FALSE ) ) {
- # Self-links are handled specially; generally de-link and change to bold.
- $s .= $prefix . $sk->makeSelfLinkObj( $nt, $text, "", $trail );
- return $s;
- }
- if( $ns == $media ) {
- $s .= $prefix . $sk->makeMediaLinkObj( $nt, $text ) . $trail;
- $wgLinkCache->addImageLinkObj( $nt );
- return $s;
- } elseif( $ns == $special ) {
- $s .= $prefix . $sk->makeKnownLinkObj( $nt, $text, "", $trail );
- return $s;
+ if( $ns == $media ) {
+ $s .= $prefix . $sk->makeMediaLinkObj( $nt, $text ) . $trail;
+ $wgLinkCache->addImageLinkObj( $nt );
+ continue;
+ } elseif( $ns == $special ) {
+ $s .= $prefix . $sk->makeKnownLinkObj( $nt, $text, '', $trail );
+ continue;
+ }
+ $s .= $sk->makeLinkObj( $nt, $text, '', $trail, $prefix );
}
- $s .= $sk->makeLinkObj( $nt, $text, "", $trail , $prefix );
-
wfProfileOut( $fname );
return $s;
}
# Some functions here used by doBlockLevels()
#
- /* private */ function closeParagraph()
- {
- $result = "";
+ /* private */ function closeParagraph() {
+ $result = '';
if ( '' != $this->mLastSection ) {
- $result = "</" . $this->mLastSection . ">\n";
+ $result = '</' . $this->mLastSection . ">\n";
}
$this->mInPre = false;
- $this->mLastSection = "";
+ $this->mLastSection = '';
return $result;
}
# getCommon() returns the length of the longest common substring
# of both arguments, starting at the beginning of both.
#
- /* private */ function getCommon( $st1, $st2 )
- {
+ /* private */ function getCommon( $st1, $st2 ) {
$fl = strlen( $st1 );
$shorter = strlen( $st2 );
if ( $fl < $shorter ) { $shorter = $fl; }
@@ -1101,53 +1169,51 @@ class Parser
{
$result = $this->closeParagraph();
- if ( "*" == $char ) { $result .= "<ul><li>"; }
- else if ( "#" == $char ) { $result .= "<ol><li>"; }
- else if ( ":" == $char ) { $result .= "<dl><dd>"; }
- else if ( ";" == $char ) {
- $result .= "<dl><dt>";
+ if ( '*' == $char ) { $result .= '<ul><li>'; }
+ else if ( '#' == $char ) { $result .= '<ol><li>'; }
+ else if ( ':' == $char ) { $result .= '<dl><dd>'; }
+ else if ( ';' == $char ) {
+ $result .= '<dl><dt>';
$this->mDTopen = true;
}
- else { $result = "<!-- ERR 1 -->"; }
+ else { $result = '<!-- ERR 1 -->'; }
return $result;
}
- /* private */ function nextItem( $char )
- {
- if ( "*" == $char || "#" == $char ) { return "</li><li>"; }
- else if ( ":" == $char || ";" == $char ) {
+ /* private */ function nextItem( $char ) {
+ if ( '*' == $char || '#' == $char ) { return '</li><li>'; }
+ else if ( ':' == $char || ';' == $char ) {
$close = "</dd>";
- if ( $this->mDTopen ) { $close = "</dt>"; }
- if ( ";" == $char ) {
+ if ( $this->mDTopen ) { $close = '</dt>'; }
+ if ( ';' == $char ) {
$this->mDTopen = true;
- return $close . "<dt>";
+ return $close . '<dt>';
} else {
$this->mDTopen = false;
- return $close . "<dd>";
+ return $close . '<dd>';
}
}
- return "<!-- ERR 2 -->";
+ return '<!-- ERR 2 -->';
}
- /* private */function closeList( $char )
- {
- if ( "*" == $char ) { $text = "</li></ul>"; }
- else if ( "#" == $char ) { $text = "</li></ol>"; }
- else if ( ":" == $char ) {
+ /* private */function closeList( $char ) {
+ if ( '*' == $char ) { $text = '</li></ul>'; }
+ else if ( '#' == $char ) { $text = '</li></ol>'; }
+ else if ( ':' == $char ) {
if ( $this->mDTopen ) {
$this->mDTopen = false;
- $text = "</dt></dl>";
+ $text = '</dt></dl>';
} else {
- $text = "</dd></dl>";
+ $text = '</dd></dl>';
}
}
- else { return "<!-- ERR 3 -->"; }
+ else { return '<!-- ERR 3 -->'; }
return $text."\n";
}
/* private */ function doBlockLevels( $text, $linestart ) {
- $fname = "Parser::doBlockLevels";
+ $fname = 'Parser::doBlockLevels';
wfProfileIn( $fname );
# Parsing through the text line by line. The main thing
@@ -1173,11 +1239,11 @@ class Parser
}
if ( !$this->mInPre ) {
# Multiple prefixes may abut each other for nested lists.
- $prefixLength = strspn( $oLine, "*#:;" );
+ $prefixLength = strspn( $oLine, '*#:;' );
$pref = substr( $oLine, 0, $prefixLength );
# eh?
- $pref2 = str_replace( ";", ":", $pref );
+ $pref2 = str_replace( ';', ':', $pref );
$t = substr( $oLine, $prefixLength );
} else {
# Don't interpret any other prefixes in preformatted text
@@ -1200,7 +1266,7 @@ class Parser
# FIXME: This is not foolproof. Something better in Tokenizer might help.
if( preg_match( '/^(.*?(?:\s|&nbsp;)):(.*)$/', $t, $match ) ) {
$term = $match[1];
- $output .= $term . $this->nextItem( ":" );
+ $output .= $term . $this->nextItem( ':' );
$t = $match[2];
}
}
@@ -1220,7 +1286,7 @@ class Parser
$char = substr( $pref, $commonPrefixLength, 1 );
$output .= $this->openList( $char );
- if ( ";" == $char ) {
+ if ( ';' == $char ) {
# FIXME: This is dupe of code above
if( preg_match( '/^(.*?(?:\s|&nbsp;)):(.*)$/', $t, $match ) ) {
$term = $match[1];
@@ -1236,10 +1302,10 @@ class Parser
# No prefix (not in list)--go to paragraph mode
$uniq_prefix = UNIQ_PREFIX;
// XXX: use a stack for nestable elements like span, table and div
- $openmatch = preg_match("/(<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<div|<pre|<tr|<td|<p|<ul|<li)/i", $t );
+ $openmatch = preg_match('/(<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<li|<\\/tr|<\\/td|<\\/th)/i', $t );
$closematch = preg_match(
- "/(<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|".
- "<\\/div|<hr|<\\/td|<\\/pre|<\\/p|".$uniq_prefix."-pre|<\\/li|<\\/ul)/i", $t );
+ '/(<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'.
+ '<td|<th|<div|<\\/div|<hr|<\\/pre|<\\/p|'.$uniq_prefix.'-pre|<\\/li|<\\/ul)/i', $t );
if ( $openmatch or $closematch ) {
$paragraphStack = false;
$output .= $this->closeParagraph();
@@ -1251,7 +1317,7 @@ class Parser
} else {
$inBlockElem = true;
}
- } else if ( !$inBlockElem ) {
+ } else if ( !$inBlockElem && !$this->mInPre ) {
if ( " " == $t{0} and trim($t) != '' ) {
// pre
if ($this->mLastSection != 'pre') {
@@ -1263,14 +1329,14 @@ class Parser
// paragraph
if ( '' == trim($t) ) {
if ( $paragraphStack ) {
- $output .= $paragraphStack.'<br/>';
+ $output .= $paragraphStack.'<br />';
$paragraphStack = false;
$this->mLastSection = 'p';
} else {
if ($this->mLastSection != 'p' ) {
$output .= $this->closeParagraph();
$this->mLastSection = '';
- $paragraphStack = "<p>";
+ $paragraphStack = '<p>';
} else {
$paragraphStack = '</p><p>';
}
@@ -1296,36 +1362,37 @@ class Parser
$output .= $this->closeList( $pref2{$prefixLength-1} );
--$prefixLength;
}
- if ( "" != $this->mLastSection ) {
- $output .= "</" . $this->mLastSection . ">";
- $this->mLastSection = "";
+ if ( '' != $this->mLastSection ) {
+ $output .= '</' . $this->mLastSection . '>';
+ $this->mLastSection = '';
}
wfProfileOut( $fname );
return $output;
}
+ # Return value of a magic variable (like PAGENAME)
function getVariableValue( $index ) {
global $wgLang, $wgSitename, $wgServer;
switch ( $index ) {
case MAG_CURRENTMONTH:
- return date( "m" );
+ return date( 'm' );
case MAG_CURRENTMONTHNAME:
- return $wgLang->getMonthName( date("n") );
+ return $wgLang->getMonthName( date('n') );
case MAG_CURRENTMONTHNAMEGEN:
- return $wgLang->getMonthNameGen( date("n") );
+ return $wgLang->getMonthNameGen( date('n') );
case MAG_CURRENTDAY:
- return date("j");
+ return date('j');
case MAG_PAGENAME:
return $this->mTitle->getText();
case MAG_NAMESPACE:
# return Namespace::getCanonicalName($this->mTitle->getNamespace());
return $wgLang->getNsText($this->mTitle->getNamespace()); // Patch by Dori
case MAG_CURRENTDAYNAME:
- return $wgLang->getWeekdayName( date("w")+1 );
+ return $wgLang->getWeekdayName( date('w')+1 );
case MAG_CURRENTYEAR:
- return date( "Y" );
+ return date( 'Y' );
case MAG_CURRENTTIME:
return $wgLang->time( wfTimestampNow(), false );
case MAG_NUMBEROFARTICLES:
@@ -1339,8 +1406,8 @@ class Parser
}
}
- function initialiseVariables()
- {
+ # initialise the magic variables (like CURRENTMONTHNAME)
+ function initialiseVariables() {
global $wgVariableIDs;
$this->mVariables = array();
foreach ( $wgVariableIDs as $id ) {
@@ -1349,11 +1416,10 @@ class Parser
}
}
- /* private */ function replaceVariables( $text, $args = array() )
- {
+ /* private */ function replaceVariables( $text, $args = array() ) {
global $wgLang, $wgScript, $wgArticlePath;
- $fname = "Parser::replaceVariables";
+ $fname = 'Parser::replaceVariables';
wfProfileIn( $fname );
$bail = false;
@@ -1361,26 +1427,49 @@ class Parser
$this->initialiseVariables();
}
$titleChars = Title::legalChars();
- $regex = "/(\\n?){{([$titleChars]*?)(\\|.*?|)}}/s";
+ $nonBraceChars = str_replace( array( '{', '}' ), array( '', '' ), $titleChars );
# This function is called recursively. To keep track of arguments we need a stack:
array_push( $this->mArgStack, $args );
# PHP global rebinding syntax is a bit weird, need to use the GLOBALS array
$GLOBALS['wgCurParser'] =& $this;
- $text = preg_replace_callback( $regex, "wfBraceSubstitution", $text );
+
+
+ if ( $this->mOutputType == OT_HTML ) {
+ # Variable substitution
+ $text = preg_replace_callback( "/{{([$nonBraceChars]*?)}}/", 'wfVariableSubstitution', $text );
+
+ # Argument substitution
+ $text = preg_replace_callback( "/(\\n?){{{([$titleChars]*?)}}}/", 'wfArgSubstitution', $text );
+ }
+ # Template substitution
+ $regex = '/(\\n?){{(['.$nonBraceChars.']*)(\\|.*?|)}}/s';
+ $text = preg_replace_callback( $regex, 'wfBraceSubstitution', $text );
array_pop( $this->mArgStack );
+ wfProfileOut( $fname );
return $text;
}
- function braceSubstitution( $matches )
- {
+ function variableSubstitution( $matches ) {
+ if ( array_key_exists( $matches[1], $this->mVariables ) ) {
+ $text = $this->mVariables[$matches[1]];
+ $this->mOutput->mContainsOldMagic = true;
+ } else {
+ $text = $matches[0];
+ }
+ return $text;
+ }
+
+ function braceSubstitution( $matches ) {
global $wgLinkCache, $wgLang;
- $fname = "Parser::braceSubstitution";
+ $fname = 'Parser::braceSubstitution';
$found = false;
$nowiki = false;
+ $noparse = false;
+
$title = NULL;
# $newline is an optional newline character before the braces
@@ -1390,26 +1479,36 @@ class Parser
$newline = $matches[1];
$part1 = $matches[2];
# If the third subpattern matched anything, it will start with |
- if ( $matches[3] !== "" ) {
- $args = explode( "|", substr( $matches[3], 1 ) );
+ if ( $matches[3] !== '' ) {
+ $args = explode( '|', substr( $matches[3], 1 ) );
} else {
$args = array();
}
$argc = count( $args );
+
+ # {{{}}}
+ if ( strpos( $matches[0], '{{{' ) !== false ) {
+ $text = $matches[0];
+ $found = true;
+ $noparse = true;
+ }
# SUBST
- $mwSubst =& MagicWord::get( MAG_SUBST );
- if ( $mwSubst->matchStartAndRemove( $part1 ) ) {
- if ( $this->mOutputType != OT_WIKI ) {
- # Invalid SUBST not replaced at PST time
- # Return without further processing
+ if ( !$found ) {
+ $mwSubst =& MagicWord::get( MAG_SUBST );
+ if ( $mwSubst->matchStartAndRemove( $part1 ) ) {
+ if ( $this->mOutputType != OT_WIKI ) {
+ # Invalid SUBST not replaced at PST time
+ # Return without further processing
+ $text = $matches[0];
+ $found = true;
+ $noparse= true;
+ }
+ } elseif ( $this->mOutputType == OT_WIKI ) {
+ # SUBST not found in PST pass, do nothing
$text = $matches[0];
$found = true;
}
- } elseif ( $this->mOutputType == OT_WIKI ) {
- # SUBST not found in PST pass, do nothing
- $text = $matches[0];
- $found = true;
}
# MSG, MSGNW and INT
@@ -1427,7 +1526,7 @@ class Parser
# Check if it is an internal message
$mwInt =& MagicWord::get( MAG_INT );
if ( $mwInt->matchStartAndRemove( $part1 ) ) {
- if ( $this->incrementIncludeCount( "int:$part1" ) ) {
+ if ( $this->incrementIncludeCount( 'int:'.$part1 ) ) {
$text = wfMsgReal( $part1, $args, true );
$found = true;
}
@@ -1484,14 +1583,14 @@ class Parser
$found = true;
$this->mOutput->mContainsOldMagic = true;
}
-
+/*
# Arguments input from the caller
$inputArgs = end( $this->mArgStack );
if ( !$found && array_key_exists( $part1, $inputArgs ) ) {
$text = $inputArgs[$part1];
$found = true;
}
-
+*/
# Load from database
if ( !$found ) {
$title = Title::newFromText( $part1, NS_TEMPLATE );
@@ -1510,7 +1609,7 @@ class Parser
# If the title is valid but undisplayable, make a link to it
if ( $this->mOutputType == OT_HTML && !$found ) {
- $text = "[[" . $title->getPrefixedText() . "]]";
+ $text = '[[' . $title->getPrefixedText() . ']]';
$found = true;
}
}
@@ -1520,19 +1619,19 @@ class Parser
# Only for HTML output
if ( $nowiki && $found && $this->mOutputType == OT_HTML ) {
$text = wfEscapeWikiText( $text );
- } elseif ( $this->mOutputType == OT_HTML && $found ) {
+ } elseif ( $this->mOutputType == OT_HTML && $found && !$noparse) {
# Clean up argument array
$assocArgs = array();
$index = 1;
foreach( $args as $arg ) {
- $eqpos = strpos( $arg, "=" );
+ $eqpos = strpos( $arg, '=' );
if ( $eqpos === false ) {
$assocArgs[$index++] = $arg;
} else {
$name = trim( substr( $arg, 0, $eqpos ) );
$value = trim( substr( $arg, $eqpos+1 ) );
if ( $value === false ) {
- $value = "";
+ $value = '';
}
if ( $name !== false ) {
$assocArgs[$name] = $value;
@@ -1546,13 +1645,7 @@ class Parser
}
# Run full parser on the included text
- $text = $this->strip( $text, $this->mStripState );
- $text = $this->internalParse( $text, (bool)$newline, $assocArgs, false );
- if(!empty($newline)) $text = "\n".$text;
-
- # Add the result to the strip state for re-inclusion after
- # the rest of the processing
- $text = $this->insertStripItem( $text, $this->mStripState );
+ $text = $this->stripParse( $text, $newline, $assocArgs );
# Resume the link cache and register the inclusion as a link
if ( !is_null( $title ) ) {
@@ -1568,9 +1661,22 @@ class Parser
}
}
+ # Triple brace replacement -- used for template arguments
+ function argSubstitution( $matches ) {
+ $newline = $matches[1];
+ $arg = trim( $matches[2] );
+ $text = $matches[0];
+ $inputArgs = end( $this->mArgStack );
+
+ if ( array_key_exists( $arg, $inputArgs ) ) {
+ $text = $this->stripParse( $inputArgs[$arg], $newline, array() );
+ }
+
+ return $text;
+ }
+
# Returns true if the function is allowed to include this entity
- function incrementIncludeCount( $dbk )
- {
+ function incrementIncludeCount( $dbk ) {
if ( !array_key_exists( $dbk, $this->mIncludeCount ) ) {
$this->mIncludeCount[$dbk] = 0;
}
@@ -1583,29 +1689,28 @@ class Parser
# Cleans up HTML, removes dangerous tags and attributes
- /* private */ function removeHTMLtags( $text )
- {
+ /* private */ function removeHTMLtags( $text ) {
global $wgUseTidy, $wgUserHtml;
- $fname = "Parser::removeHTMLtags";
+ $fname = 'Parser::removeHTMLtags';
wfProfileIn( $fname );
if( $wgUserHtml ) {
$htmlpairs = array( # Tags that must be closed
- "b", "del", "i", "ins", "u", "font", "big", "small", "sub", "sup", "h1",
- "h2", "h3", "h4", "h5", "h6", "cite", "code", "em", "s",
- "strike", "strong", "tt", "var", "div", "center",
- "blockquote", "ol", "ul", "dl", "table", "caption", "pre",
- "ruby", "rt" , "rb" , "rp", "p"
+ 'b', 'del', 'i', 'ins', 'u', 'font', 'big', 'small', 'sub', 'sup', 'h1',
+ 'h2', 'h3', 'h4', 'h5', 'h6', 'cite', 'code', 'em', 's',
+ 'strike', 'strong', 'tt', 'var', 'div', 'center',
+ 'blockquote', 'ol', 'ul', 'dl', 'table', 'caption', 'pre',
+ 'ruby', 'rt' , 'rb' , 'rp', 'p'
);
$htmlsingle = array(
- "br", "hr", "li", "dt", "dd"
+ 'br', 'hr', 'li', 'dt', 'dd'
);
$htmlnest = array( # Tags that can be nested--??
- "table", "tr", "td", "th", "div", "blockquote", "ol", "ul",
- "dl", "font", "big", "small", "sub", "sup"
+ 'table', 'tr', 'td', 'th', 'div', 'blockquote', 'ol', 'ul',
+ 'dl', 'font', 'big', 'small', 'sub', 'sup'
);
$tabletags = array( # Can only appear inside table
- "td", "th", "tr"
+ 'td', 'th', 'tr'
);
} else {
$htmlpairs = array();
@@ -1620,15 +1725,15 @@ class Parser
$htmlattrs = $this->getHTMLattrs () ;
# Remove HTML comments
- $text = preg_replace( "/(\\n *<!--.*--> *(?=\\n)|<!--.*-->)/sU", "$2", $text );
+ $text = preg_replace( '/(\\n *<!--.*--> *(?=\\n)|<!--.*-->)/sU', '$2', $text );
- $bits = explode( "<", $text );
+ $bits = explode( '<', $text );
$text = array_shift( $bits );
if(!$wgUseTidy) {
$tagstack = array(); $tablestack = array();
foreach ( $bits as $x ) {
$prev = error_reporting( E_ALL & ~( E_NOTICE | E_WARNING ) );
- preg_match( "/^(\\/?)(\\w+)([^>]*)(\\/{0,1}>)([^<]*)$/",
+ preg_match( '/^(\\/?)(\\w+)([^>]*)(\\/{0,1}>)([^<]*)$/',
$x, $regs );
list( $qbar, $slash, $t, $params, $brace, $rest ) = $regs;
error_reporting( $prev );
@@ -1639,25 +1744,25 @@ class Parser
if ( $slash ) {
# Closing a tag...
if ( ! in_array( $t, $htmlsingle ) &&
- ( count($tagstack) && $ot = array_pop( $tagstack ) ) != $t ) {
- if(!empty($ot)) array_push( $tagstack, $ot );
+ ( $ot = @array_pop( $tagstack ) ) != $t ) {
+ @array_push( $tagstack, $ot );
$badtag = 1;
} else {
- if ( $t == "table" ) {
+ if ( $t == 'table' ) {
$tagstack = array_pop( $tablestack );
}
- $newparams = "";
+ $newparams = '';
}
} else {
# Keep track for later
if ( in_array( $t, $tabletags ) &&
- ! in_array( "table", $tagstack ) ) {
+ ! in_array( 'table', $tagstack ) ) {
$badtag = 1;
} else if ( in_array( $t, $tagstack ) &&
! in_array ( $t , $htmlnest ) ) {
$badtag = 1 ;
} else if ( ! in_array( $t, $htmlsingle ) ) {
- if ( $t == "table" ) {
+ if ( $t == 'table' ) {
array_push( $tablestack, $tagstack );
$tagstack = array();
}
@@ -1668,30 +1773,30 @@ class Parser
}
if ( ! $badtag ) {
- $rest = str_replace( ">", "&gt;", $rest );
+ $rest = str_replace( '>', '&gt;', $rest );
$text .= "<$slash$t $newparams$brace$rest";
continue;
}
}
- $text .= "&lt;" . str_replace( ">", "&gt;", $x);
+ $text .= '&lt;' . str_replace( '>', '&gt;', $x);
}
# Close off any remaining tags
- while ( $t = array_pop( $tagstack ) ) {
+ while ( is_array( $tagstack ) && ($t = array_pop( $tagstack )) ) {
$text .= "</$t>\n";
- if ( $t == "table" ) { $tagstack = array_pop( $tablestack ); }
+ if ( $t == 'table' ) { $tagstack = array_pop( $tablestack ); }
}
} else {
# this might be possible using tidy itself
foreach ( $bits as $x ) {
- preg_match( "/^(\\/?)(\\w+)([^>]*)(\\/{0,1}>)([^<]*)$/",
+ preg_match( '/^(\\/?)(\\w+)([^>]*)(\\/{0,1}>)([^<]*)$/',
$x, $regs );
@list( $qbar, $slash, $t, $params, $brace, $rest ) = $regs;
if ( in_array( $t = strtolower( $t ), $htmlelements ) ) {
$newparams = $this->fixTagAttributes($params);
- $rest = str_replace( ">", "&gt;", $rest );
+ $rest = str_replace( '>', '&gt;', $rest );
$text .= "<$slash$t $newparams$brace$rest";
} else {
- $text .= "&lt;" . str_replace( ">", "&gt;", $x);
+ $text .= '&lt;' . str_replace( '>', '&gt;', $x);
}
}
}
@@ -1713,8 +1818,7 @@ class Parser
*
*/
- /* private */ function formatHeadings( $text, $isMain=true )
- {
+ /* private */ function formatHeadings( $text, $isMain=true ) {
global $wgInputEncoding;
$doNumberHeadings = $this->mOptions->getNumberHeadings();
@@ -1741,13 +1845,13 @@ class Parser
# never add the TOC to the Main Page. This is an entry page that should not
# be more than 1-2 screens large anyway
- if( $this->mTitle->getPrefixedText() == wfMsg("mainpage") ) {
+ if( $this->mTitle->getPrefixedText() == wfMsg('mainpage') ) {
$doShowToc = 0;
}
# Get all headlines for numbering them and adding funky stuff like [edit]
# links - this is for later, but we need the number of headlines right now
- $numMatches = preg_match_all( "/<H([1-6])(.*?" . ">)(.*?)<\/H[1-6]>/i", $text, $matches );
+ $numMatches = preg_match_all( '/<H([1-6])(.*?' . '>)(.*?)<\/H[1-6]>/i', $text, $matches );
# if there are fewer than 4 headlines in the article, do not show TOC
if( $numMatches < 4 ) {
@@ -1771,14 +1875,14 @@ class Parser
# Ugh .. the TOC should have neat indentation levels which can be
# passed to the skin functions. These are determined here
$toclevel = 0;
- $toc = "";
- $full = "";
+ $toc = '';
+ $full = '';
$head = array();
$sublevelCount = array();
$level = 0;
$prevlevel = 0;
foreach( $matches[3] as $headline ) {
- $numbering = "";
+ $numbering = '';
if( $level ) {
$prevlevel = $level;
}
@@ -1802,7 +1906,7 @@ class Parser
for( $i = 1; $i <= $level; $i++ ) {
if( !empty( $sublevelCount[$i] ) ) {
if( $dot ) {
- $numbering .= ".";
+ $numbering .= '.';
}
$numbering .= $sublevelCount[$i];
$dot = 1;
@@ -1813,13 +1917,17 @@ class Parser
# The canonized header is a version of the header text safe to use for links
# Avoid insertion of weird stuff like <math> by expanding the relevant sections
$canonized_headline = $this->unstrip( $headline, $this->mStripState );
+ $canonized_headline = $this->unstripNoWiki( $headline, $this->mStripState );
# strip out HTML
- $canonized_headline = preg_replace( "/<.*?" . ">/","",$canonized_headline );
+ $canonized_headline = preg_replace( '/<.*?' . '>/','',$canonized_headline );
$tocline = trim( $canonized_headline );
- $canonized_headline = preg_replace("/[ \\?&\\/<>\\(\\)\\[\\]=,+']+/", '_', urlencode( do_html_entity_decode( $tocline, ENT_COMPAT, $wgInputEncoding ) ) );
- # strip out urlencoded &nbsp; (inserted for french spaces, e.g. first space in 'something : something')
- $canonized_headline = str_replace('%C2%A0','_', $canonized_headline);
+ $canonized_headline = urlencode( do_html_entity_decode( str_replace(' ', '_', $tocline), ENT_COMPAT, $wgInputEncoding ) );
+ $replacearray = array(
+ '%3A' => ':',
+ '%' => '.'
+ );
+ $canonized_headline = str_replace(array_keys($replacearray),array_values($replacearray),$canonized_headline);
$refer[$headlineCount] = $canonized_headline;
# count how many in assoc. array so we can track dupes in anchors
@@ -1829,26 +1937,26 @@ class Parser
# Prepend the number to the heading text
if( $doNumberHeadings || $doShowToc ) {
- $tocline = $numbering . " " . $tocline;
+ $tocline = $numbering . ' ' . $tocline;
# Don't number the heading if it is the only one (looks silly)
if( $doNumberHeadings && count( $matches[3] ) > 1) {
# the two are different if the line contains a link
- $headline=$numbering . " " . $headline;
+ $headline=$numbering . ' ' . $headline;
}
}
# Create the anchor for linking from the TOC to the section
$anchor = $canonized_headline;
if($refcount[$headlineCount] > 1 ) {
- $anchor .= "_" . $refcount[$headlineCount];
+ $anchor .= '_' . $refcount[$headlineCount];
}
if( $doShowToc ) {
$toc .= $sk->tocLine($anchor,$tocline,$toclevel);
}
if( $showEditLink ) {
if ( empty( $head[$headlineCount] ) ) {
- $head[$headlineCount] = "";
+ $head[$headlineCount] = '';
}
$head[$headlineCount] .= $sk->editSectionLink($headlineCount+1);
}
@@ -1872,7 +1980,7 @@ class Parser
# split up and insert constructed headlines
- $blocks = preg_split( "/<H[1-6].*?" . ">.*?<\/H[1-6]>/i", $text );
+ $blocks = preg_split( '/<H[1-6].*?' . '>.*?<\/H[1-6]>/i', $text );
$i = 0;
foreach( $blocks as $block ) {
@@ -1899,73 +2007,54 @@ class Parser
return $full;
}
- /* private */ function doMagicISBN( &$tokenizer )
- {
+ # Return an HTML link for the "ISBN 123456" text
+ /* private */ function magicISBN( $text ) {
global $wgLang;
- # Check whether next token is a text token
- # If yes, fetch it and convert the text into a
- # Special::BookSources link
- $token = $tokenizer->previewToken();
- while ( $token["type"] == "" )
- {
- $tokenizer->nextToken();
- $token = $tokenizer->previewToken();
- }
- if ( $token["type"] == "text" )
- {
- $token = $tokenizer->nextToken();
- $x = $token["text"];
- $valid = "0123456789-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ $a = split( 'ISBN ', " $text" );
+ if ( count ( $a ) < 2 ) return $text;
+ $text = substr( array_shift( $a ), 1);
+ $valid = '0123456789-ABCDEFGHIJKLMNOPQRSTUVWXYZ';
- $isbn = $blank = "" ;
- while ( " " == $x{0} ) {
- $blank .= " ";
+ foreach ( $a as $x ) {
+ $isbn = $blank = '' ;
+ while ( ' ' == $x{0} ) {
+ $blank .= ' ';
$x = substr( $x, 1 );
}
while ( strstr( $valid, $x{0} ) != false ) {
$isbn .= $x{0};
$x = substr( $x, 1 );
}
- $num = str_replace( "-", "", $isbn );
- $num = str_replace( " ", "", $num );
+ $num = str_replace( '-', '', $isbn );
+ $num = str_replace( ' ', '', $num );
- if ( "" == $num ) {
- $text = "ISBN $blank$x";
+ if ( '' == $num ) {
+ $text .= "ISBN $blank$x";
} else {
- $titleObj = Title::makeTitle( NS_SPECIAL, "Booksources" );
- $text = "<a href=\"" .
+ $titleObj = Title::makeTitle( NS_SPECIAL, 'Booksources' );
+ $text .= '<a href="' .
$titleObj->escapeLocalUrl( "isbn={$num}" ) .
"\" class=\"internal\">ISBN $isbn</a>";
$text .= $x;
}
- } else {
- $text = "ISBN ";
}
return $text;
}
- /* private */ function doMagicRFC( &$tokenizer )
- {
+
+ # Return an HTML link for the "RFC 1234" text
+ /* private */ function magicRFC( $text ) {
global $wgLang;
- # Check whether next token is a text token
- # If yes, fetch it and convert the text into a
- # link to an RFC source
- $token = $tokenizer->previewToken();
- while ( $token["type"] == "" )
- {
- $tokenizer->nextToken();
- $token = $tokenizer->previewToken();
- }
- if ( $token["type"] == "text" )
- {
- $token = $tokenizer->nextToken();
- $x = $token["text"];
- $valid = "0123456789";
+ $a = split( 'RFC ', ' '.$text );
+ if ( count ( $a ) < 2 ) return $text;
+ $text = substr( array_shift( $a ), 1);
+ $valid = '0123456789';
- $rfc = $blank = "" ;
- while ( " " == $x{0} ) {
- $blank .= " ";
+ foreach ( $a as $x ) {
+ $rfc = $blank = '' ;
+ while ( ' ' == $x{0} ) {
+ $blank .= ' ';
$x = substr( $x, 1 );
}
while ( strstr( $valid, $x{0} ) != false ) {
@@ -1973,23 +2062,20 @@ class Parser
$x = substr( $x, 1 );
}
- if ( "" == $rfc ) {
+ if ( '' == $rfc ) {
$text .= "RFC $blank$x";
} else {
- $url = wfmsg( "rfcurl" );
- $url = str_replace( "$1", $rfc, $url);
+ $url = wfmsg( 'rfcurl' );
+ $url = str_replace( '$1', $rfc, $url);
$sk =& $this->mOptions->getSkin();
$la = $sk->getExternalLinkAttributes( $url, "RFC {$rfc}" );
- $text = "<a href='{$url}'{$la}>RFC {$rfc}</a>{$x}";
+ $text .= "<a href='{$url}'{$la}>RFC {$rfc}</a>{$x}";
}
- } else {
- $text = "RFC ";
}
return $text;
}
- function preSaveTransform( $text, &$title, &$user, $options, $clearState = true )
- {
+ function preSaveTransform( $text, &$title, &$user, $options, $clearState = true ) {
$this->mOptions = $options;
$this->mTitle =& $title;
$this->mOutputType = OT_WIKI;
@@ -2004,19 +2090,21 @@ class Parser
);
$text = str_replace(array_keys($pairs), array_values($pairs), $text);
// now with regexes
+ /*
$pairs = array(
"/<br.+(clear|break)=[\"']?(all|both)[\"']?\\/?>/i" => '<br style="clear:both;"/>',
- "/<br *?>/i" => "<br/>",
+ "/<br *?>/i" => "<br />",
);
$text = preg_replace(array_keys($pairs), array_values($pairs), $text);
+ */
$text = $this->strip( $text, $stripState, false );
$text = $this->pstPass2( $text, $user );
$text = $this->unstrip( $text, $stripState );
+ $text = $this->unstripNoWiki( $text, $stripState );
return $text;
}
- /* private */ function pstPass2( $text, &$user )
- {
+ /* private */ function pstPass2( $text, &$user ) {
global $wgLang, $wgLocaltimezone, $wgCurParser;
# Variable replacement
@@ -2026,20 +2114,20 @@ class Parser
# Signatures
#
$n = $user->getName();
- $k = $user->getOption( "nickname" );
- if ( "" == $k ) { $k = $n; }
+ $k = $user->getOption( 'nickname' );
+ if ( '' == $k ) { $k = $n; }
if(isset($wgLocaltimezone)) {
- $oldtz = getenv("TZ"); putenv("TZ=$wgLocaltimezone");
+ $oldtz = getenv('TZ'); putenv('TZ='.$wgLocaltimezone);
}
/* Note: this is an ugly timezone hack for the European wikis */
- $d = $wgLang->timeanddate( date( "YmdHis" ), false ) .
- " (" . date( "T" ) . ")";
- if(isset($wgLocaltimezone)) putenv("TZ=$oldtz");
+ $d = $wgLang->timeanddate( date( 'YmdHis' ), false ) .
+ ' (' . date( 'T' ) . ')';
+ if(isset($wgLocaltimezone)) putenv('TZ='.$oldtzs);
- $text = preg_replace( "/~~~~~/", $d, $text );
- $text = preg_replace( "/~~~~/", "[[" . $wgLang->getNsText(
+ $text = preg_replace( '/~~~~~/', $d, $text );
+ $text = preg_replace( '/~~~~/', '[[' . $wgLang->getNsText(
Namespace::getUser() ) . ":$n|$k]] $d", $text );
- $text = preg_replace( "/~~~/", "[[" . $wgLang->getNsText(
+ $text = preg_replace( '/~~~/', '[[' . $wgLang->getNsText(
Namespace::getUser() ) . ":$n|$k]]", $text );
# Context links: [[|name]] and [[name (context)|]]
@@ -2059,12 +2147,12 @@ class Parser
if ( preg_match( $conpat, $t, $m ) ) {
$context = $m[2];
}
- $text = preg_replace( $p4, "[[\\1:\\2 (\\3)|\\2]]", $text );
- $text = preg_replace( $p1, "[[\\1 (\\2)|\\1]]", $text );
- $text = preg_replace( $p3, "[[\\1:\\2|\\2]]", $text );
+ $text = preg_replace( $p4, '[[\\1:\\2 (\\3)|\\2]]', $text );
+ $text = preg_replace( $p1, '[[\\1 (\\2)|\\1]]', $text );
+ $text = preg_replace( $p3, '[[\\1:\\2|\\2]]', $text );
- if ( "" == $context ) {
- $text = preg_replace( $p2, "[[\\1]]", $text );
+ if ( '' == $context ) {
+ $text = preg_replace( $p2, '[[\\1]]', $text );
} else {
$text = preg_replace( $p2, "[[\\1 ({$context})|\\1]]", $text );
}
@@ -2088,8 +2176,7 @@ class Parser
# Set up some variables which are usually set up in parse()
# so that an external function can call some class members with confidence
- function startExternalParse( &$title, $options, $outputType, $clearState = true )
- {
+ function startExternalParse( &$title, $options, $outputType, $clearState = true ) {
$this->mTitle =& $title;
$this->mOptions = $options;
$this->mOutputType = $outputType;
@@ -2117,11 +2204,21 @@ class Parser
$executing = false;
return $text;
}
+
+ # Create an HTML-style tag, e.g. <yourtag>special text</yourtag>
+ # Callback will be called with the text within
+ # Transform and return the text within
+ function setHook( $tag, $callback ) {
+ $oldVal = @$this->mTagHooks[$tag];
+ $this->mTagHooks[$tag] = $callback;
+ return $oldVal;
+ }
}
class ParserOutput
{
var $mText, $mLanguageLinks, $mCategoryLinks, $mContainsOldMagic;
+ var $mCacheTime; # Used in ParserCache
function ParserOutput( $text = "", $languageLinks = array(), $categoryLinks = array(),
$containsOldMagic = false )
@@ -2130,16 +2227,19 @@ class ParserOutput
$this->mLanguageLinks = $languageLinks;
$this->mCategoryLinks = $categoryLinks;
$this->mContainsOldMagic = $containsOldMagic;
+ $this->mCacheTime = "";
}
function getText() { return $this->mText; }
function getLanguageLinks() { return $this->mLanguageLinks; }
function getCategoryLinks() { return $this->mCategoryLinks; }
+ function getCacheTime() { return $this->mCacheTime; }
function containsOldMagic() { return $this->mContainsOldMagic; }
function setText( $text ) { return wfSetVar( $this->mText, $text ); }
function setLanguageLinks( $ll ) { return wfSetVar( $this->mLanguageLinks, $ll ); }
function setCategoryLinks( $cl ) { return wfSetVar( $this->mCategoryLinks, $cl ); }
function setContainsOldMagic( $com ) { return wfSetVar( $this->mContainsOldMagic, $com ); }
+ function setCacheTime( $t ) { return wfSetVar( $this->mCacheTime, $t ); }
function merge( $other ) {
$this->mLanguageLinks = array_merge( $this->mLanguageLinks, $other->mLanguageLinks );
@@ -2164,39 +2264,38 @@ class ParserOptions
var $mNumberHeadings; # Automatically number headings
var $mShowToc; # Show table of contents
- function getUseTeX() { return $this->mUseTeX; }
- function getUseCategoryMagic() { return $this->mUseCategoryMagic; }
- function getUseDynamicDates() { return $this->mUseDynamicDates; }
- function getInterwikiMagic() { return $this->mInterwikiMagic; }
- function getAllowExternalImages() { return $this->mAllowExternalImages; }
- function getSkin() { return $this->mSkin; }
- function getDateFormat() { return $this->mDateFormat; }
- function getEditSection() { return $this->mEditSection; }
- function getEditSectionOnRightClick() { return $this->mEditSectionOnRightClick; }
- function getNumberHeadings() { return $this->mNumberHeadings; }
- function getShowToc() { return $this->mShowToc; }
-
- function setUseTeX( $x ) { return wfSetVar( $this->mUseTeX, $x ); }
- function setUseCategoryMagic( $x ) { return wfSetVar( $this->mUseCategoryMagic, $x ); }
- function setUseDynamicDates( $x ) { return wfSetVar( $this->mUseDynamicDates, $x ); }
- function setInterwikiMagic( $x ) { return wfSetVar( $this->mInterwikiMagic, $x ); }
- function setAllowExternalImages( $x ) { return wfSetVar( $this->mAllowExternalImages, $x ); }
- function setSkin( $x ) { return wfSetRef( $this->mSkin, $x ); }
- function setDateFormat( $x ) { return wfSetVar( $this->mDateFormat, $x ); }
- function setEditSection( $x ) { return wfSetVar( $this->mEditSection, $x ); }
- function setEditSectionOnRightClick( $x ) { return wfSetVar( $this->mEditSectionOnRightClick, $x ); }
- function setNumberHeadings( $x ) { return wfSetVar( $this->mNumberHeadings, $x ); }
- function setShowToc( $x ) { return wfSetVar( $this->mShowToc, $x ); }
-
- /* static */ function newFromUser( &$user )
- {
+ function getUseTeX() { return $this->mUseTeX; }
+ function getUseCategoryMagic() { return $this->mUseCategoryMagic; }
+ function getUseDynamicDates() { return $this->mUseDynamicDates; }
+ function getInterwikiMagic() { return $this->mInterwikiMagic; }
+ function getAllowExternalImages() { return $this->mAllowExternalImages; }
+ function getSkin() { return $this->mSkin; }
+ function getDateFormat() { return $this->mDateFormat; }
+ function getEditSection() { return $this->mEditSection; }
+ function getEditSectionOnRightClick() { return $this->mEditSectionOnRightClick; }
+ function getNumberHeadings() { return $this->mNumberHeadings; }
+ function getShowToc() { return $this->mShowToc; }
+
+ function setUseTeX( $x ) { return wfSetVar( $this->mUseTeX, $x ); }
+ function setUseCategoryMagic( $x ) { return wfSetVar( $this->mUseCategoryMagic, $x ); }
+ function setUseDynamicDates( $x ) { return wfSetVar( $this->mUseDynamicDates, $x ); }
+ function setInterwikiMagic( $x ) { return wfSetVar( $this->mInterwikiMagic, $x ); }
+ function setAllowExternalImages( $x ) { return wfSetVar( $this->mAllowExternalImages, $x ); }
+ function setDateFormat( $x ) { return wfSetVar( $this->mDateFormat, $x ); }
+ function setEditSection( $x ) { return wfSetVar( $this->mEditSection, $x ); }
+ function setEditSectionOnRightClick( $x ) { return wfSetVar( $this->mEditSectionOnRightClick, $x ); }
+ function setNumberHeadings( $x ) { return wfSetVar( $this->mNumberHeadings, $x ); }
+ function setShowToc( $x ) { return wfSetVar( $this->mShowToc, $x ); }
+
+ function setSkin( &$x ) { $this->mSkin =& $x; }
+
+ /* static */ function newFromUser( &$user ) {
$popts = new ParserOptions;
$popts->initialiseFromUser( $user );
return $popts;
}
- function initialiseFromUser( &$userInput )
- {
+ function initialiseFromUser( &$userInput ) {
global $wgUseTeX, $wgUseCategoryMagic, $wgUseDynamicDates, $wgInterwikiMagic, $wgAllowExternalImages;
if ( !$userInput ) {
@@ -2212,11 +2311,11 @@ class ParserOptions
$this->mInterwikiMagic = $wgInterwikiMagic;
$this->mAllowExternalImages = $wgAllowExternalImages;
$this->mSkin =& $user->getSkin();
- $this->mDateFormat = $user->getOption( "date" );
- $this->mEditSection = $user->getOption( "editsection" );
- $this->mEditSectionOnRightClick = $user->getOption( "editsectiononrightclick" );
- $this->mNumberHeadings = $user->getOption( "numberheadings" );
- $this->mShowToc = $user->getOption( "showtoc" );
+ $this->mDateFormat = $user->getOption( 'date' );
+ $this->mEditSection = $user->getOption( 'editsection' );
+ $this->mEditSectionOnRightClick = $user->getOption( 'editsectiononrightclick' );
+ $this->mNumberHeadings = $user->getOption( 'numberheadings' );
+ $this->mShowToc = $user->getOption( 'showtoc' );
}
@@ -2229,4 +2328,16 @@ function wfBraceSubstitution( $matches )
return $wgCurParser->braceSubstitution( $matches );
}
+function wfArgSubstitution( $matches )
+{
+ global $wgCurParser;
+ return $wgCurParser->argSubstitution( $matches );
+}
+
+function wfVariableSubstitution( $matches )
+{
+ global $wgCurParser;
+ return $wgCurParser->variableSubstitution( $matches );
+}
+
?>
diff --git a/includes/ParserCache.php b/includes/ParserCache.php
index 70b994365caf..8634a3b7d657 100644
--- a/includes/ParserCache.php
+++ b/includes/ParserCache.php
@@ -2,67 +2,62 @@
class ParserCache
{
- function get( &$article, &$user ){
+ function getKey( &$article, &$user ) {
+ global $wgDBname;
$hash = $user->getPageRenderingHash();
- $pageid = intval( $id );
- $res = wfQuery("SELECT pc_data FROM parsercache WHERE pc_pageid = {$pageid} ".
- " AND pc_prefhash = '{$hash}' AND pc_expire > NOW()", DB_WRITE);
- $row = wfFetchObject ( $res );
- if( $row ){
- $retVal = unserialize( gzuncompress($row->pc_data) );
- wfProfileOut( $fname );
- } else {
- $retVal = false;
- }
- return $retVal;
+ $pageid = intval( $article->getID() );
+ $key = "$wgDBname:pcache:idhash:$pageid-$hash";
+ return $key;
}
+
+ function get( &$article, &$user ) {
+ global $wgMemc, $wgCacheEpoch;
+ $fname = "ParserCache::get";
+ wfProfileIn( $fname );
- function save( $parserOutput, &$article, &$user ){
$hash = $user->getPageRenderingHash();
$pageid = intval( $article->getID() );
- $title = wfStrencode( $article->mTitle->getPrefixedDBKey() );
- $ser = addslashes( gzcompress( serialize( $parserOutput ) ) );
- if( $parserOutput->containsOldMagic() ){
- $expire = "1 HOUR";
+ $key = $this->getKey( $article, $user );
+ wfDebug( "Trying parser cache $key\n" );
+ $value = $wgMemc->get( $key );
+ if ( $value ) {
+ wfDebug( "Found.\n" );
+ # Delete if article has changed since the cache was made
+ $canCache = $article->checkTouched();
+ $cacheTime = $value->getCacheTime();
+ $touched = $article->mTouched;
+ if ( !$canCache || $value->getCacheTime() <= $touched || $cacheTime < $wgCacheEpoch ) {
+ if ( !$canCache ) {
+ wfDebug( "Invalid cached redirect, touched $touched, epoch $wgCacheEpoch, cached $cacheTime\n" );
+ } else {
+ wfDebug( "Key expired, touched $touched, epoch $wgCacheEpoch, cached $cacheTime\n" );
+ }
+ $wgMemc->delete( $key );
+ $value = false;
+ }
} else {
- $expire = "7 DAY";
+ $value = false;
}
- wfQuery("REPLACE INTO parsercache (pc_prefhash,pc_pageid,pc_title,pc_data, pc_expire) ".
- "VALUES('{$hash}', {$pageid}, '{$title}', '{$ser}', ".
- "DATE_ADD(NOW(), INTERVAL {$expire}))", DB_WRITE);
-
- if( rand() % 50 == 0 ){ // more efficient to just do it sometimes
- $this->purge();
- }
+ wfProfileOut( $fname );
+ return $value;
}
- function purge(){
- wfQuery("DELETE FROM parsercache WHERE pc_expire < NOW() LIMIT 250", DB_WRITE);
- }
+ function save( $parserOutput, &$article, &$user ){
+ global $wgMemc;
- function clearLinksTo( $pid ){
- $pid = intval( $pid );
- wfQuery("DELETE parsercache FROM parsercache,links ".
- "WHERE pc_pageid=links.l_from AND l_to={$pid}", DB_WRITE);
- wfQuery("DELETE FROM parsercache WHERE pc_pageid='{$pid}'", DB_WRITE);
- }
+ $key = $this->getKey( $article, $user );
+ $now = wfTimestampNow();
+ $parserOutput->setCacheTime( $now );
+ $parserOutput->mText .= "\n<!-- Saved in parser cache with key $key and timestamp $now -->\n";
- # $title is a prefixed db title, for example like Title->getPrefixedDBkey() returns.
- function clearBrokenLinksTo( $title ){
- $title = wfStrencode( $title );
- wfQuery("DELETE parsercache FROM parsercache,brokenlinks ".
- "WHERE pc_pageid=bl_from AND bl_to='{$title}'", DB_WRITE);
- }
-
- # $pid is a page id
- function clearPage( $pid, $namespace ){
- $pid = intval( $pid );
- if( $namespace == NS_MEDIAWIKI ){
- $this->clearLinksTo( $pid );
+ if( $parserOutput->containsOldMagic() ){
+ $expire = 3600; # 1 hour
} else {
- wfQuery("DELETE FROM parsercache WHERE pc_pageid='{$pid}'", DB_WRITE);
+ $expire = 86400; # 1 day
}
+
+ $wgMemc->set( $key, $parserOutput, $expire );
}
}
diff --git a/includes/Profiling.php b/includes/Profiling.php
index 392ca38f1247..ed58bf08d80a 100755
--- a/includes/Profiling.php
+++ b/includes/Profiling.php
@@ -82,6 +82,7 @@ class Profiler
if( !count( $this->mStack ) ) {
return "No profiling output\n";
}
+ $this->close();
$width = 125;
$format = "%-" . ($width - 28) . "s %6d %6.3f %6.3f %6.3f%%\n";
$titleFormat = "%-" . ($width - 28) . "s %9s %9s %9s %9s\n";
@@ -173,5 +174,4 @@ class Profiler
$wgProfiler = new Profiler();
$wgProfiler->profileIn( "-total" );
-
?>
diff --git a/includes/QueryPage.php b/includes/QueryPage.php
index 6ffd11662326..43804cee26e8 100644
--- a/includes/QueryPage.php
+++ b/includes/QueryPage.php
@@ -37,7 +37,7 @@ class QueryPage {
function getOrderLimit( $offset, $limit ) {
return " ORDER BY value " .
($this->sortDescending() ? "DESC" : "")
- . " LIMIT {$offset}, {$limit}";
+ . wfLimitResult($limit,$offset);
}
# Is this query expensive (for some definition of expensive)? Then we
diff --git a/includes/RawPage.php b/includes/RawPage.php
index b218612a9637..4116f005667c 100644
--- a/includes/RawPage.php
+++ b/includes/RawPage.php
@@ -8,36 +8,74 @@
class RawPage {
function RawPage( $article ) {
- global $wgRequest, $wgInputEncoding;
+ global $wgRequest, $wgInputEncoding, $wgSquidMaxage;
$allowedCTypes = array('text/x-wiki', 'text/javascript', 'text/css', 'application/x-zope-edit');
$this->mArticle =& $article;
$this->mTitle =& $article->mTitle;
+
$ctype = $wgRequest->getText( 'ctype' );
+ $charset = $wgRequest->getText( 'charset' );
+ $smaxage = $wgRequest->getText( 'smaxage' );
+ $maxage = $wgRequest->getText( 'maxage' );
+ $this->mOldId = $wgRequest->getInt( 'oldid' );
+ # special case for 'generated' raw things: user css/js
+ $gen = $wgRequest->getText( 'gen' );
+ if($gen == 'css') {
+ $this->mGen = $gen;
+ if($smaxage == '') $smaxage = $wgSquidMaxage;
+ if($ctype == '') $ctype = 'text/css';
+ } else if ($gen == 'js') {
+ $this->mGen = $gen;
+ if($smaxage == '') $smaxage = $wgSquidMaxage;
+ if($ctype == '') $ctype = 'text/javascript';
+ } else {
+ $this->mGen = false;
+ }
+ $this->mCharset = !empty($charset) ? $charset : $wgInputEncoding;
+ $this->mSmaxage = ($smaxage != '') ? $smaxage : 0;
+ $this->mMaxage = ($maxage != '') ? $maxage : 86400;
if(empty($ctype) or !in_array($ctype, $allowedCTypes)) {
$this->mContentType = 'text/x-wiki';
} else {
$this->mContentType = $ctype;
}
-
- $charset = $wgRequest->getText( 'charset' );
- $this->mCharset = !empty($charset) ? $charset : $wgInputEncoding;
- $this->mOldId = $wgRequest->getInt( 'oldid' );
}
function view() {
+ global $wgUser, $wgOut;
header( "Content-type: ".$this->mContentType.'; charset='.$this->mCharset );
# allow the client to cache this for 24 hours
- header( 'Cache-Control: s-maxage=0, max-age=86400' );
- echo $this->getrawtext();
+ header( 'Cache-Control: s-maxage='.$this->mSmaxage.', max-age='.$this->mMaxage );
+ if($this->mGen) {
+ $sk = $wgUser->getSkin();
+ $sk->initPage($wgOut);
+ if($this->mGen == 'css') {
+ echo $sk->getUserStylesheet();
+ } else if($this->mGen == 'js') {
+ echo $sk->getUserJs();
+ }
+ } else {
+ echo $this->getrawtext();
+ }
wfAbruptExit();
}
function getrawtext () {
- global $wgInputEncoding, $wgLang;
+ global $wgInputEncoding, $wgLang, $wgIsPg;
if( !$this->mTitle ) return '';
$t = wfStrencode( $this->mTitle->getDBKey() );
$ns = $this->mTitle->getNamespace();
+ # special case
+ if($ns == NS_MEDIAWIKI) {
+ $rawtext = wfMsg($t);
+ if($wgInputEncoding != $this->mCharset)
+ $rawtext = $wgLang->iconv( $wgInputEncoding, $this->mCharset, $rawtext );
+ return $rawtext;
+ }
+ # else get it from the DB
if(!empty($this->mOldId)) {
- $sql = "SELECT old_text as text,old_timestamp as timestamp,old_user as user,old_flags as flags FROM old " .
+ $oldtable=$wgIsPg?'"old"':'old';
+ $sql = "SELECT old_text AS text,old_timestamp AS timestamp,".
+ "old_user AS user,old_flags AS flags FROM $oldtable " .
"WHERE old_id={$this->mOldId}";
} else {
$sql = "SELECT cur_id as id,cur_timestamp as timestamp,cur_user as user,cur_user_text as user_text," .
diff --git a/includes/RecentChange.php b/includes/RecentChange.php
index fb385bca24b1..ed64ee213cad 100644
--- a/includes/RecentChange.php
+++ b/includes/RecentChange.php
@@ -5,6 +5,8 @@ define( "RC_EDIT", 0);
define( "RC_NEW", 1);
define( "RC_MOVE", 2);
define( "RC_LOG", 3);
+define( "RC_MOVE_OVER_REDIRECT", 4);
+
/*
mAttributes:
@@ -21,6 +23,7 @@ mAttributes:
rc_this_oldid old_id associated with this entry (or zero)
rc_last_oldid old_id associated with the entry before this one (or zero)
rc_bot is bot, hidden
+ rc_ip IP address of the user in dotted quad notation
rc_new obsolete, use rc_type==RC_NEW
mExtra:
@@ -82,7 +85,7 @@ class RecentChange
# Writes the data in this object to the database
function save()
{
- global $wgUseRCQueue, $wgRCQueueID, $wgLocalInterwiki;
+ global $wgUseRCQueue, $wgRCQueueID, $wgLocalInterwiki, $wgPutIPinRC;
$fname = "RecentChange::save";
if ( !is_array($this->mExtra) ) {
@@ -90,6 +93,10 @@ class RecentChange
}
$this->mExtra['lang'] = $wgLocalInterwiki;
+ if ( !$wgPutIPinRC ) {
+ $this->mAttribs['rc_ip'] = '';
+ }
+
# Insert new row
wfInsertArray( "recentchanges", $this->mAttribs, $fname );
@@ -126,12 +133,17 @@ class RecentChange
# Makes an entry in the database corresponding to an edit
/*static*/ function notifyEdit( $timestamp, &$title, $minor, &$user, $comment,
- $oldId, $lastTimestamp, $bot = "default" )
+ $oldId, $lastTimestamp, $bot = "default", $ip = '' )
{
if ( $bot == "default " ) {
$bot = $user->isBot();
}
+ if ( !$ip ) {
+ global $wgIP;
+ $ip = empty( $wgIP ) ? '' : $wgIP;
+ }
+
$rc = new RecentChange;
$rc->mAttribs = array(
'rc_timestamp' => $timestamp,
@@ -149,6 +161,7 @@ class RecentChange
'rc_bot' => $bot ? 1 : 0,
'rc_moved_to_ns' => 0,
'rc_moved_to_title' => '',
+ 'rc_ip' => $ip,
'rc_new' => 0 # obsolete
);
@@ -161,28 +174,34 @@ class RecentChange
# Makes an entry in the database corresponding to page creation
# Note: the title object must be loaded with the new id using resetArticleID()
- /*static*/ function notifyNew( $timestamp, &$title, $minor, &$user, $comment, $bot = "default" )
+ /*static*/ function notifyNew( $timestamp, &$title, $minor, &$user, $comment, $bot = "default", $ip='' )
{
+ if ( !$ip ) {
+ global $wgIP;
+ $ip = empty( $wgIP ) ? '' : $wgIP;
+ }
if ( $bot == "default" ) {
$bot = $user->isBot();
}
+
$rc = new RecentChange;
$rc->mAttribs = array(
- 'rc_timestamp' => $timestamp,
- 'rc_cur_time' => $timestamp,
- 'rc_namespace' => $title->getNamespace(),
- 'rc_title' => $title->getDBkey(),
- 'rc_type' => RC_NEW,
- 'rc_minor' => $minor ? 1 : 0,
- 'rc_cur_id' => $title->getArticleID(),
- 'rc_user' => $user->getID(),
- 'rc_user_text' => $user->getName(),
- 'rc_comment' => $comment,
- 'rc_this_oldid' => 0,
- 'rc_last_oldid' => 0,
- 'rc_bot' => $bot ? 1 : 0,
- 'rc_moved_to_ns' => 0,
- 'rc_moved_to_title' => '',
+ 'rc_timestamp' => $timestamp,
+ 'rc_cur_time' => $timestamp,
+ 'rc_namespace' => $title->getNamespace(),
+ 'rc_title' => $title->getDBkey(),
+ 'rc_type' => RC_NEW,
+ 'rc_minor' => $minor ? 1 : 0,
+ 'rc_cur_id' => $title->getArticleID(),
+ 'rc_user' => $user->getID(),
+ 'rc_user_text' => $user->getName(),
+ 'rc_comment' => $comment,
+ 'rc_this_oldid' => 0,
+ 'rc_last_oldid' => 0,
+ 'rc_bot' => $bot ? 1 : 0,
+ 'rc_moved_to_ns' => 0,
+ 'rc_moved_to_title' => '',
+ 'rc_ip' => $ip,
'rc_new' => 1 # obsolete
);
@@ -194,15 +213,19 @@ class RecentChange
}
# Makes an entry in the database corresponding to a rename
- /*static*/ function notifyMove( $timestamp, &$oldTitle, &$newTitle, &$user, $comment )
+ /*static*/ function notifyMove( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='', $overRedir = false )
{
+ if ( !$ip ) {
+ global $wgIP;
+ $ip = empty( $wgIP ) ? '' : $wgIP;
+ }
$rc = new RecentChange;
$rc->mAttribs = array(
'rc_timestamp' => $timestamp,
'rc_cur_time' => $timestamp,
'rc_namespace' => $oldTitle->getNamespace(),
'rc_title' => $oldTitle->getDBkey(),
- 'rc_type' => RC_MOVE,
+ 'rc_type' => $overRedir ? RC_MOVE_OVER_REDIRECT : RC_MOVE,
'rc_minor' => 0,
'rc_cur_id' => $oldTitle->getArticleID(),
'rc_user' => $user->getID(),
@@ -213,6 +236,7 @@ class RecentChange
'rc_bot' => $user->isBot() ? 1 : 0,
'rc_moved_to_ns' => $newTitle->getNamespace(),
'rc_moved_to_title' => $newTitle->getDBkey(),
+ 'rc_ip' => $ip,
'rc_new' => 0 # obsolete
);
@@ -224,10 +248,22 @@ class RecentChange
$rc->save();
}
+ /* static */ function notifyMoveToNew( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='' ) {
+ RecentChange::notifyMove( $timestamp, $oldTitle, $newTitle, $user, $comment, $ip, false );
+ }
+
+ /* static */ function notifyMoveOverRedirect( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='' ) {
+ RecentChange::notifyMove( $timestamp, $oldTitle, $newTitle, $user, $comment, $ip='', true );
+ }
+
# A log entry is different to an edit in that previous revisions are
# not kept
- /*static*/ function notifyLog( $timestamp, &$title, &$user, $comment )
+ /*static*/ function notifyLog( $timestamp, &$title, &$user, $comment, $ip='' )
{
+ if ( !$ip ) {
+ global $wgIP;
+ $ip = empty( $wgIP ) ? '' : $wgIP;
+ }
$rc = new RecentChange;
$rc->mAttribs = array(
'rc_timestamp' => $timestamp,
@@ -245,6 +281,7 @@ class RecentChange
'rc_bot' => 0,
'rc_moved_to_ns' => 0,
'rc_moved_to_title' => '',
+ 'rc_ip' => $ip,
'rc_new' => 0 # obsolete
);
$rc->mExtra = array(
@@ -280,6 +317,7 @@ class RecentChange
'rc_bot' => 0,
'rc_moved_to_ns' => 0,
'rc_moved_to_title' => '',
+ 'rc_ip' => '',
'rc_new' => $row->cur_is_new # obsolete
);
diff --git a/includes/SearchEngine.php b/includes/SearchEngine.php
index 19a081b302f7..53d9e691591b 100644
--- a/includes/SearchEngine.php
+++ b/includes/SearchEngine.php
@@ -296,6 +296,8 @@ class SearchEngine {
# Use cleaner boolean search if available
return $this->parseQuery4();
}
+ # on non mysql4 database: get list of words we don't want to search for
+ require_once( "FulltextStoplist.php" );
$lc = SearchEngine::legalSearchChars() . "()";
$q = preg_replace( "/([()])/", " \\1 ", $this->mUsertext );
@@ -485,8 +487,13 @@ class SearchEngine {
$wgOut->redirect( $t->getFullURL( "action=edit" ) );
return;
}
-
- $wgOut->addHTML( "<p>" . wfMsg("nogomatch", $t->escapeLocalURL( "action=edit" ) ) . "</p>\n" );
+
+ if( $t ) {
+ $editurl = $t->escapeLocalURL( "action=edit" );
+ } else {
+ $editurl = ""; # ??
+ }
+ $wgOut->addHTML( "<p>" . wfMsg("nogomatch", $editurl ) . "</p>\n" );
# Try a fuzzy title search
$anyhit = false;
diff --git a/includes/SearchUpdate.php b/includes/SearchUpdate.php
index 08f66eab88ed..c7b9c6103c32 100644
--- a/includes/SearchUpdate.php
+++ b/includes/SearchUpdate.php
@@ -1,4 +1,5 @@
<?php
+# $Id$
# See deferred.doc
class SearchUpdate {
@@ -24,7 +25,7 @@ class SearchUpdate {
function doUpdate()
{
- global $wgDBminWordLen, $wgLang, $wgDisableSearchUpdate;
+ global $wgDBminWordLen, $wgLang, $wgDisableSearchUpdate, $wgIsMySQL;
if( $wgDisableSearchUpdate || !$this->mId ) {
return false;
@@ -32,7 +33,8 @@ class SearchUpdate {
$lc = SearchEngine::legalSearchChars() . "&#;";
if( $this->mText == false ) {
# Just update the title
- $sql = "UPDATE LOW_PRIORITY searchindex SET si_title='" .
+ $lowpri=$wgIsMySQL?"LOW_PRIORITY":"";
+ $sql = "UPDATE $lowpri searchindex SET si_title='" .
wfStrencode( Title::indexTitle( $this->mNamespace, $this->mTitle ) ) .
"' WHERE si_page={$this->mId}";
wfQuery( $sql, DB_WRITE, "SearchUpdate::doUpdate" );
@@ -75,7 +77,7 @@ class SearchUpdate {
# Strip wiki '' and '''
$text = preg_replace( "/''[']*/", " ", $text );
- $sql = "REPLACE DELAYED INTO searchindex (si_page,si_title,si_text) VALUES ({$this->mId},'" .
+ $sql = "REPLACE INTO searchindex (si_page,si_title,si_text) VALUES ({$this->mId},'" .
wfStrencode( Title::indexTitle( $this->mNamespace, $this->mTitle ) ) . "','" .
wfStrencode( $text ) . "')";
wfQuery( $sql, DB_WRITE, "SearchUpdate::doUpdate" );
diff --git a/includes/Setup.php b/includes/Setup.php
index 7a668080fa0a..21d5ef39315e 100644
--- a/includes/Setup.php
+++ b/includes/Setup.php
@@ -11,72 +11,73 @@ if( !isset( $wgProfiling ) )
$wgProfiling = false;
if ( $wgProfiling and (0 == rand() % $wgProfileSampleRate ) ) {
- require_once( "Profiling.php" );
+ require_once( 'Profiling.php' );
} else {
- function wfProfileIn( $fn ) {}
- function wfProfileOut( $fn = "" ) {}
+ function wfProfileIn( $fn = '' ) {}
+ function wfProfileOut( $fn = '' ) {}
function wfGetProfilingOutput( $s, $e ) {}
function wfProfileClose() {}
}
/* collect the originating ips */
-if( $wgUseSquid && isset( $_SERVER["HTTP_X_FORWARDED_FOR"] ) ) {
+if( $wgUseSquid && isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
# If the web server is behind a reverse proxy, we need to find
# out where our requests are really coming from.
- $hopips = array_map( "trim", explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] ) );
+ $hopips = array_map( 'trim', explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] ) );
while(in_array(trim(end($hopips)), $wgSquidServers)){
array_pop($hopips);
}
$wgIP = trim(end($hopips));
} else {
- $wgIP = getenv("REMOTE_ADDR");
+ $wgIP = getenv('REMOTE_ADDR');
}
-$fname = "Setup.php";
+$fname = 'Setup.php';
wfProfileIn( $fname );
global $wgUseDynamicDates;
-wfProfileIn( "$fname-includes" );
-
-require_once( "GlobalFunctions.php" );
-require_once( "Namespace.php" );
-require_once( "RecentChange.php" );
-require_once( "Skin.php" );
-require_once( "OutputPage.php" );
-require_once( "User.php" );
-require_once( "LinkCache.php" );
-require_once( "Title.php" );
-require_once( "Article.php" );
-require_once( "MagicWord.php" );
-require_once( "memcached-client.php" );
-require_once( "Block.php" );
-require_once( "SearchEngine.php" );
-require_once( "DifferenceEngine.php" );
-require_once( "MessageCache.php" );
-require_once( "BlockCache.php" );
-require_once( "Parser.php" );
-require_once( "ParserCache.php" );
-require_once( "WebRequest.php" );
-require_once( "SpecialPage.php" );
+wfProfileIn( $fname.'-includes' );
+
+require_once( 'GlobalFunctions.php' );
+require_once( 'Namespace.php' );
+require_once( 'RecentChange.php' );
+require_once( 'User.php' );
+require_once( 'Skin.php' );
+require_once( 'OutputPage.php' );
+require_once( 'LinkCache.php' );
+require_once( 'Title.php' );
+require_once( 'Article.php' );
+require_once( 'MagicWord.php' );
+require_once( 'memcached-client.php' );
+require_once( 'Block.php' );
+require_once( 'SearchEngine.php' );
+require_once( 'DifferenceEngine.php' );
+require_once( 'MessageCache.php' );
+require_once( 'BlockCache.php' );
+require_once( 'Parser.php' );
+require_once( 'ParserCache.php' );
+require_once( 'WebRequest.php' );
+require_once( 'LoadBalancer.php' );
$wgRequest = new WebRequest();
-wfProfileOut( "$fname-includes" );
-wfProfileIn( "$fname-memcached" );
+wfProfileOut( $fname.'-includes' );
+wfProfileIn( $fname.'-memcached' );
global $wgUser, $wgLang, $wgOut, $wgTitle;
global $wgArticle, $wgDeferredUpdateList, $wgLinkCache;
global $wgMemc, $wgMagicWords, $wgMwRedir, $wgDebugLogFile;
global $wgMessageCache, $wgUseMemCached, $wgUseDatabaseMessages;
global $wgMsgCacheExpiry, $wgDBname, $wgCommandLineMode;
-global $wgBlockCache, $wgParserCache, $wgParser;
+global $wgBlockCache, $wgParserCache, $wgParser, $wgDBConnections;
+global $wgLoadBalancer, $wgDBservers, $wgDBloads, $wgDBuser, $wgDBpassword;
# Useful debug output
if ( $wgCommandLineMode ) {
# wfDebug( '"' . implode( '" "', $argv ) . '"' );
-} elseif ( function_exists( "getallheaders" ) ) {
+} elseif ( function_exists( 'getallheaders' ) ) {
wfDebug( "\nStart request\n" );
wfDebug( $_SERVER['REQUEST_METHOD'] . ' ' . $_SERVER['REQUEST_URI'] . "\n" );
$headers = getallheaders();
@@ -126,7 +127,7 @@ if( $wgUseMemCached ) {
# Test it to see if it's working
# This is necessary because otherwise wfMsg would be extremely inefficient
- if ( !$wgMemc->set( "test", "", 0 ) ) {
+ if ( !$wgMemc->set( 'test', '', 0 ) ) {
wfDebug( "Memcached failed setup test - connection error?\n" );
$wgUseMemCached = false;
$wgMemc = new FakeMemCachedClient();
@@ -137,43 +138,80 @@ if( $wgUseMemCached ) {
# Give the message cache a separate cache in the DB.
# This is a speedup over separately querying every message used
- require_once( "ObjectCache.php" );
- $messageMemc = new MediaWikiBagOStuff("objectcache");
+ require_once( 'ObjectCache.php' );
+ $messageMemc = new MediaWikiBagOStuff('objectcache');
}
-wfProfileOut( "$fname-memcached" );
-wfProfileIn( "$fname-misc" );
+wfProfileOut( $fname.'-memcached' );
+wfProfileIn( $fname.'-database' );
-require_once( "languages/Language.php" );
+if ( !$wgDBservers ) {
+ $wgDBservers = array( $wgDBserver );
+ $wgDBloads = array( 1 );
+}
+$wgLoadBalancer = LoadBalancer::newFromParams( $wgDBservers, $wgDBloads, $wgDBuser, $wgDBpassword, $wgDBname );
+$wgLoadBalancer->force(0);
+
+wfProfileOut( $fname.'-database' );
+wfProfileIn( $fname.'-language' );
+require_once( 'languages/Language.php' );
$wgMessageCache = new MessageCache;
-$wgLangClass = "Language" . ucfirst( $wgLanguageCode );
-if( ! class_exists( $wgLangClass ) || ($wgLanguageCode == "en" && strcasecmp( $wgInputEncoding, "utf-8" ) == 0 ) ) {
- require_once( "languages/LanguageUtf8.php" );
- $wgLangClass = "LanguageUtf8";
+$wgLangClass = 'Language' . ucfirst( $wgLanguageCode );
+if( ! class_exists( $wgLangClass ) || ($wgLanguageCode == 'en' && !$wgUseLatin1) ) {
+ # Default to English/UTF-8
+ require_once( 'languages/LanguageUtf8.php' );
+ $wgLangClass = 'LanguageUtf8';
}
$wgLang = new $wgLangClass();
if ( !is_object($wgLang) ) {
print "No language class ($wgLang)\N";
}
+
+if( $wgUseLatin1 && $wgLanguageCode != 'en' ) {
+ # For non-UTF-8 non-English.
+ require_once( 'languages/LanguageLatin1.php' );
+ $xxx = new LanguageLatin1( $wgLang );
+ unset( $wgLang );
+ $wgLang = $xxx;
+}
+wfProfileOut( $fname.'-language' );
+wfProfileIn( $fname.'-MessageCache' );
+
$wgMessageCache->initialise( $messageMemc, $wgUseDatabaseMessages, $wgMsgCacheExpiry, $wgDBname );
+wfProfileOut( $fname.'-MessageCache' );
+wfProfileIn( $fname.'-OutputPage' );
+
$wgOut = new OutputPage();
wfDebug( "\n\n" );
+wfProfileOut( $fname.'-OutputPage' );
+wfProfileIn( $fname.'-DateFormatter' );
+
if ( $wgUseDynamicDates ) {
- require_once( "DateFormatter.php" );
+ require_once( 'DateFormatter.php' );
global $wgDateFormatter;
$wgDateFormatter = new DateFormatter;
}
-if( !$wgCommandLineMode && ( isset( $_COOKIE[ini_get("session.name")] ) || isset( $_COOKIE["{$wgDBname}Password"] ) ) ) {
+wfProfileOut( $fname.'-DateFormatter' );
+wfProfileIn( $fname.'-SetupSession' );
+
+if( !$wgCommandLineMode && ( isset( $_COOKIE[ini_get('session.name')] ) || isset( $_COOKIE[$wgDBname.'Password'] ) ) ) {
User::SetupSession();
}
+wfProfileOut( $fname.'-SetupSession' );
+wfProfileIn( $fname.'-BlockCache' );
+
$wgBlockCache = new BlockCache( true );
+
+wfProfileOut( $fname.'-BlockCache' );
+wfProfileIn( $fname.'-User' );
+
if( $wgCommandLineMode ) {
# Used for some maintenance scripts; user session cookies can screw things up
# when the database is in an in-between state.
@@ -181,6 +219,10 @@ if( $wgCommandLineMode ) {
} else {
$wgUser = User::loadFromSession();
}
+
+wfProfileOut( $fname.'-User' );
+wfProfileIn( $fname.'-misc' );
+
$wgDeferredUpdateList = array();
$wgLinkCache = new LinkCache();
$wgMagicWords = array();
@@ -188,10 +230,14 @@ $wgMwRedir =& MagicWord::get( MAG_REDIRECT );
$wgParserCache = new ParserCache();
$wgParser = new Parser();
$wgOut->setParserOptions( ParserOptions::newFromUser( $wgUser ) );
+$wgDBConnections = array();
-if ( !$wgAllowSysopQueries ) {
- SpecialPage::removePage( "Asksql" );
-}
+# Placeholders in case of DB error
+$wgTitle = Title::newFromText( wfMsg( 'badtitle' ) );
+$wgArticle = new Article($wgTitle);
+
+wfProfileOut( $fname.'-misc' );
+wfProfileIn( $fname.'-extensions' );
# Extension setup functions
# Entries should be added to this variable during the inclusion
@@ -201,7 +247,7 @@ foreach ( $wgExtensionFunctions as $func ) {
$func();
}
-wfProfileOut( "$fname-misc" );
+wfProfileOut( $fname.'-extensions' );
wfProfileOut( $fname );
diff --git a/includes/SiteConfiguration.php b/includes/SiteConfiguration.php
new file mode 100644
index 000000000000..aa0a6b56aa55
--- /dev/null
+++ b/includes/SiteConfiguration.php
@@ -0,0 +1,65 @@
+<?php
+
+# This file is used to configure the live Wikimedia wikis. The file that includes
+# it contains passwords and other sensitive data, and there's currently no public
+# equivalent.
+
+class SiteConfiguration {
+ var $suffixes, $wikis, $settings;
+ var $localDatabases;
+
+ function get( $setting, $wiki, $suffix, $params = array() ) {
+ if ( array_key_exists( $wiki, $this->settings[$setting] ) ) {
+ $retval = $this->settings[$setting][$wiki];
+ } elseif ( array_key_exists( $suffix, $this->settings[$setting] ) ) {
+ $retval = $this->settings[$setting][$suffix];
+ } elseif ( array_key_exists( "default", $this->settings[$setting] ) ) {
+ $retval = $this->settings[$setting]['default'];
+ } else {
+ $retval = NULL;
+ }
+ if ( !is_null( $retval ) && count( $params ) ) {
+ foreach ( $params as $key => $value ) {
+ $retval = str_replace( '$' . $key, $value, $retval );
+ }
+ }
+ return $retval;
+ }
+
+ function getBool( $setting, $wiki, $suffix ) {
+ return (bool)($this->get( $setting, $wiki, $suffix ));
+ }
+
+ function &getLocalDatabases() {
+ return $this->localDatabases();
+ }
+
+ function initialise() {
+ foreach ( $this->wikis as $db ) {
+ $this->localDatabases[$db] = $db;
+ }
+ }
+
+ function extractVar( $setting, $wiki, $suffix, &$var, $params ) {
+ $value = $this->get( $setting, $wiki, $suffix, $params );
+ if ( !is_null( $value ) ) {
+ $var = $value;
+ }
+ }
+
+ function extractGlobal( $setting, $wiki, $suffix, $params ) {
+ $value = $this->get( $setting, $wiki, $suffix, $params );
+ if ( !is_null( $value ) ) {
+ $GLOBALS[$setting] = $value;
+ }
+ }
+
+ function extractAllGlobals( $wiki, $suffix, $params ) {
+ foreach ( $this->settings as $varName => $setting ) {
+ $this->extractGlobal( $varName, $wiki, $suffix, $params );
+ }
+ }
+}
+
+
+?>
diff --git a/includes/SiteStatsUpdate.php b/includes/SiteStatsUpdate.php
index 4c4b32cde084..900956b6398d 100644
--- a/includes/SiteStatsUpdate.php
+++ b/includes/SiteStatsUpdate.php
@@ -1,4 +1,5 @@
<?php
+# $Id$
# See deferred.doc
class SiteStatsUpdate {
@@ -14,6 +15,7 @@ class SiteStatsUpdate {
function doUpdate()
{
+ global $wgIsMySQL;
$a = array();
if ( $this->mViews < 0 ) { $m = "-1"; }
@@ -30,8 +32,8 @@ class SiteStatsUpdate {
else if ( $this->mGood > 0 ) { $m = "+1"; }
else $m = "";
array_push( $a, "ss_good_articles=(ss_good_articles$m)" );
-
- $sql = "UPDATE LOW_PRIORITY site_stats SET " . implode ( ",", $a ) .
+ $lowpri=$wgIsMySQL?"LOW_PRIORITY":"";
+ $sql = "UPDATE $lowpri site_stats SET " . implode ( ",", $a ) .
" WHERE ss_row_id=1";
wfQuery( $sql, DB_WRITE, "SiteStatsUpdate::doUpdate" );
}
diff --git a/includes/Skin.php b/includes/Skin.php
index 91faf5b5d590..37d6d479e446 100644
--- a/includes/Skin.php
+++ b/includes/Skin.php
@@ -1,33 +1,33 @@
<?php
-
-require_once( "Feed.php" );
-require_once( "Image.php" );
-
# See skin.doc
+require_once( 'Feed.php' ); // should not be called if the actual page isn't feed enabled
+require_once( 'Image.php' );
+
# These are the INTERNAL names, which get mapped
# directly to class names. For display purposes, the
# Language class has internationalized names
#
/* private */ $wgValidSkinNames = array(
- 'standard' => "Standard",
- 'nostalgia' => "Nostalgia",
- 'cologneblue' => "CologneBlue"
+ 'standard' => 'Standard',
+ 'nostalgia' => 'Nostalgia',
+ 'cologneblue' => 'CologneBlue'
);
if( $wgUsePHPTal ) {
- #$wgValidSkinNames[] = "PHPTal";
- #$wgValidSkinNames['davinci'] = "DaVinci";
- #$wgValidSkinNames['mono'] = "Mono";
- $wgValidSkinNames['monobook'] = "MonoBook";
- #$wgValidSkinNames['monobookminimal'] = "MonoBookMinimal";
+ #$wgValidSkinNames[] = 'PHPTal';
+ #$wgValidSkinNames['davinci'] = 'DaVinci';
+ #$wgValidSkinNames['mono'] = 'Mono';
+ $wgValidSkinNames['monobook'] = 'MonoBook';
+ $wgValidSkinNames['myskin'] = 'MySkin';
+ #$wgValidSkinNames['monobookminimal'] = 'MonoBookMinimal';
}
-require_once( "RecentChange.php" );
+require_once( 'RecentChange.php' );
class RCCacheEntry extends RecentChange
{
var $secureName, $link;
- var $curlink , $lastlink , $usertalklink , $versionlink ;
+ var $curlink , $difflink, $lastlink , $usertalklink , $versionlink ;
var $userlink, $timestamp, $watched;
function newFromParent( $rc )
@@ -49,7 +49,7 @@ class Skin {
function Skin()
{
- $this->linktrail = wfMsg("linktrail");
+ $this->linktrail = wfMsg('linktrail');
}
function getSkinNames()
@@ -60,7 +60,10 @@ class Skin {
function getStylesheet()
{
- return "wikistandard.css";
+ return 'wikistandard.css';
+ }
+ function getSkinName() {
+ return "standard";
}
function qbSetting()
@@ -68,17 +71,17 @@ class Skin {
global $wgOut, $wgUser;
if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
- $q = $wgUser->getOption( "quickbar" );
- if ( "" == $q ) { $q = 0; }
+ $q = $wgUser->getOption( 'quickbar' );
+ if ( '' == $q ) { $q = 0; }
return $q;
}
function initPage( &$out )
{
- $fname = "Skin::initPage";
+ $fname = 'Skin::initPage';
wfProfileIn( $fname );
- $out->addLink( array( "rel" => "shortcut icon", "href" => "/favicon.ico" ) );
+ $out->addLink( array( 'rel' => 'shortcut icon', 'href' => '/favicon.ico' ) );
$this->addMetadataLinks($out);
@@ -95,16 +98,16 @@ class Skin {
$out->addMetadataLink( array(
'title' => 'Creative Commons',
'type' => 'application/rdf+xml',
- 'href' => $wgTitle->getLocalURL( "action=creativecommons") ) );
+ 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
}
if( $wgEnableDublinCoreRdf ) {
$out->addMetadataLink( array(
'title' => 'Dublin Core',
'type' => 'application/rdf+xml',
- 'href' => $wgTitle->getLocalURL( "action=dublincore" ) ) );
+ 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
}
}
- $copyright = "";
+ $copyright = '';
if( $wgRightsPage ) {
$copy = Title::newFromText( $wgRightsPage );
if( $copy ) {
@@ -116,15 +119,15 @@ class Skin {
}
if( $copyright ) {
$out->addLink( array(
- "rel" => "copyright",
- "href" => $copyright ) );
+ 'rel' => 'copyright',
+ 'href' => $copyright ) );
}
}
function outputPage( &$out ) {
global $wgDebugComments;
- wfProfileIn( "Skin::outputPage" );
+ wfProfileIn( 'Skin::outputPage' );
$this->initPage( $out );
$out->out( $out->headElement() );
@@ -151,20 +154,45 @@ class Skin {
}
function getHeadScripts() {
- global $wgStylePath;
+ global $wgStylePath, $wgUser, $wgLang;
$r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
+ if( $wgUser->getID() != 0 ) { # logged in
+ $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
+ $userjs = htmlspecialchars($this->makeUrl($userpage.'/'.$this->getSkinName().'.js', 'action=raw&ctype=text/javascript'));
+ $r .= '<script type="text/javascript" src="'.$userjs."\"></script>\n";
+ }
return $r;
}
+ # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
+ function getUserStylesheet() {
+ global $wgOut, $wgStylePath, $wgLang, $wgUser, $wgRequest, $wgTitle;
+ $sheet = $this->getStylesheet();
+ $action = $wgRequest->getText('action');
+ $s = "@import \"$wgStylePath/$sheet\";\n";
+ if($wgLang->isRTL()) $s .= "@import \"$wgStylePath/common_rtl.css\";\n";
+ if( $wgUser->getID() != 0 ) { # logged in
+ if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
+ $s .= $wgRequest->getText('wpTextbox1');
+ } else {
+ $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
+ $s.= '@import "'.$this->makeUrl($userpage.'/'.$this->getSkinName().'.css', 'action=raw&ctype=text/css').'";'."\n";
+ }
+ }
+ $s .= $this->doGetUserStyles();
+ return $s."\n";
+ }
+ # placeholder, returns generated js in monobook
+ function getUserJs() {
+ return;
+ }
+
function getUserStyles()
{
global $wgOut, $wgStylePath, $wgLang;
- $sheet = $this->getStylesheet();
$s = "<style type='text/css'>\n";
$s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
- $s .= "@import url(\"$wgStylePath/$sheet\");\n";
- if($wgLang->isRTL()) $s .= "@import url(\"$wgStylePath/common_rtl.css\");\n";
- $s .= $this->doGetUserStyles();
+ $s .= $this->getUserStylesheet();
$s .= "/* */\n";
$s .= "</style>\n";
return $s;
@@ -174,19 +202,19 @@ class Skin {
{
global $wgUser;
- $s = "";
- if ( 1 == $wgUser->getOption( "underline" ) ) {
+ $s = '';
+ if ( 1 == $wgUser->getOption( 'underline' ) ) {
# Don't override browser settings
} else {
# CHECK MERGE @@@
# Force no underline
- $s .= "a { " .
+ $s .= 'a { ' .
"text-decoration: none; }\n";
}
- if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
+ if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
$s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
}
- if ( 1 == $wgUser->getOption( "justify" ) ) {
+ if ( 1 == $wgUser->getOption( 'justify' ) ) {
$s .= "#article { text-align: justify; }\n";
}
return $s;
@@ -199,13 +227,13 @@ class Skin {
extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
if ( 0 != $wgTitle->getNamespace() ) {
- $a = array( "bgcolor" => "#ffffec" );
+ $a = array( 'bgcolor' => '#ffffec' );
}
- else $a = array( "bgcolor" => "#FFFFFF" );
- if($wgOut->isArticle() && $wgUser->getOption("editondblclick") &&
+ else $a = array( 'bgcolor' => '#FFFFFF' );
+ if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
(!$wgTitle->isProtected() || $wgUser->isSysop()) ) {
- $t = wfMsg( "editthispage" );
- $oid = $red = "";
+ $t = wfMsg( 'editthispage' );
+ $oid = $red = '';
if ( !empty($redirect) ) {
$red = "&redirect={$redirect}";
}
@@ -213,26 +241,26 @@ class Skin {
$oid = "&oldid={$oldid}";
}
$s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
- $s = "document.location = \"" .$s ."\";";
- $a += array ("ondblclick" => $s);
+ $s = 'document.location = "' .$s .'";';
+ $a += array ('ondblclick' => $s);
}
$a['onload'] = $wgOut->getOnloadHandler();
return $a;
}
- function getExternalLinkAttributes( $link, $text )
+ function getExternalLinkAttributes( $link, $text, $class='' )
{
global $wgUser, $wgOut, $wgLang;
$link = urldecode( $link );
$link = $wgLang->checkTitleEncoding( $link );
- $link = str_replace( "_", " ", $link );
+ $link = str_replace( '_', ' ', $link );
$link = wfEscapeHTML( $link );
- $r = " class='external'";
+ $r = ($class != '') ? " class='$class'" : " class='external'";
- if ( 1 == $wgUser->getOption( "hover" ) ) {
+ if ( 1 == $wgUser->getOption( 'hover' ) ) {
$r .= " title=\"{$link}\"";
}
return $r;
@@ -243,18 +271,18 @@ class Skin {
global $wgUser, $wgOut;
$link = urldecode( $link );
- $link = str_replace( "_", " ", $link );
+ $link = str_replace( '_', ' ', $link );
$link = wfEscapeHTML( $link );
- if ( $broken == "stub" ) {
- $r = " class='stub'";
- } else if ( $broken == "yes" ) {
- $r = " class='new'";
+ if ( $broken == 'stub' ) {
+ $r = ' class="stub"';
+ } else if ( $broken == 'yes' ) {
+ $r = ' class="new"';
} else {
- $r = "";
+ $r = '';
}
- if ( 1 == $wgUser->getOption( "hover" ) ) {
+ if ( 1 == $wgUser->getOption( 'hover' ) ) {
$r .= " title=\"{$link}\"";
}
return $r;
@@ -264,15 +292,15 @@ class Skin {
{
global $wgUser, $wgOut;
- if ( $broken == "stub" ) {
- $r = " class='stub'";
- } else if ( $broken == "yes" ) {
- $r = " class='new'";
+ if ( $broken == 'stub' ) {
+ $r = ' class="stub"';
+ } else if ( $broken == 'yes' ) {
+ $r = ' class="new"';
} else {
- $r = "";
+ $r = '';
}
- if ( 1 == $wgUser->getOption( "hover" ) ) {
+ if ( 1 == $wgUser->getOption( 'hover' ) ) {
$r .= ' title ="' . $nt->getEscapedText() . '"';
}
return $r;
@@ -292,9 +320,9 @@ class Skin {
global $wgUser, $wgOut, $wgSiteNotice;
if( $wgSiteNotice ) {
- $note = "\n<div id='notice' style='font-weight: bold; color: red; text-align: center'>$wgSiteNotice</div>\n";
+ $note = "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
} else {
- $note = "";
+ $note = '';
}
return $this->doBeforeContent() . $note;
}
@@ -302,19 +330,19 @@ class Skin {
function doBeforeContent()
{
global $wgUser, $wgOut, $wgTitle, $wgLang;
- $fname = "Skin::doBeforeContent";
+ $fname = 'Skin::doBeforeContent';
wfProfileIn( $fname );
- $s = "";
+ $s = '';
$qb = $this->qbSetting();
if( $langlinks = $this->otherLanguages() ) {
$rows = 2;
- $borderhack = "";
+ $borderhack = '';
} else {
$rows = 1;
$langlinks = false;
- $borderhack = "class='top'";
+ $borderhack = 'class="top"';
}
$s .= "\n<div id='content'>\n<div id='topbar'>\n" .
@@ -326,11 +354,11 @@ class Skin {
if ( !$shove ) {
$s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
- $this->logoText() . "</td>";
+ $this->logoText() . '</td>';
} elseif( $left ) {
$s .= $this->getQuickbarCompensator( $rows );
}
- $l = $wgLang->isRTL() ? "right" : "left";
+ $l = $wgLang->isRTL() ? 'right' : 'left';
$s .= "<td {$borderhack} align='$l' valign='top'>\n";
$s .= $this->topLinks() ;
@@ -358,18 +386,35 @@ class Skin {
return $s;
}
- function getCategories () {
+ function getCategoryLinks () {
global $wgOut, $wgTitle, $wgUser, $wgParser;
- global $wgUseCategoryMagic;
- if( !$wgUseCategoryMagic ) return "" ;
- if( count( $wgOut->mCategoryLinks ) == 0 ) return "";
- if( !$wgOut->isArticle() ) return "";
+ global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
+
+ if( !$wgUseCategoryMagic ) return '' ;
+ if( count( $wgOut->mCategoryLinks ) == 0 ) return '';
+
+ # Taken out so that they will be displayed in previews -- TS
+ #if( !$wgOut->isArticle() ) return '';
+
+ $t = implode ( ' | ' , $wgOut->mCategoryLinks ) ;
+ $s = $this->makeKnownLink( 'Special:Categories',
+ wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
+ . ': ' . $t;
+
+ if($wgUseCategoryBrowser) {
+ $s .= '<br/><hr/>';
+ $catstack = array();
+ $s.= $wgTitle->getAllParentCategories($catstack);
+ }
- $t = implode ( " | " , $wgOut->mCategoryLinks ) ;
- $s = $this->makeKnownLink( "Special:Categories",
- wfMsg( "categories" ), "article=" . urlencode( $wgTitle->getPrefixedDBkey() ) )
- . ": " . $t;
- return "<p class='catlinks'>$s</p>";
+ return $s;
+ }
+
+ function getCategories() {
+ $catlinks=$this->getCategoryLinks();
+ if(!empty($catlinks)) {
+ return "<p class='catlinks'>{$catlinks}</p>";
+ }
}
function getQuickbarCompensator( $rows = 1 )
@@ -398,16 +443,16 @@ class Skin {
function doAfterContent()
{
global $wgUser, $wgOut, $wgLang;
- $fname = "Skin::doAfterContent";
+ $fname = 'Skin::doAfterContent';
wfProfileIn( $fname );
- wfProfileIn( "$fname-1" );
+ wfProfileIn( $fname.'-1' );
$s = "\n</div><br style=\"clear:both\" />\n";
$s .= "\n<div id='footer'>";
- $s .= "<table border='0' cellspacing='0'><tr>";
+ $s .= '<table border="0" cellspacing="0"><tr>';
- wfProfileOut( "$fname-1" );
- wfProfileIn( "$fname-2" );
+ wfProfileOut( $fname.'-1' );
+ wfProfileIn( $fname.'-2' );
$qb = $this->qbSetting();
$shove = ($qb != 0);
@@ -417,17 +462,17 @@ class Skin {
if ( $shove && $left ) { # Left
$s .= $this->getQuickbarCompensator();
}
- wfProfileOut( "$fname-2" );
- wfProfileIn( "$fname-3" );
- $l = $wgLang->isRTL() ? "right" : "left";
+ wfProfileOut( $fname.'-2' );
+ wfProfileIn( $fname.'-3' );
+ $l = $wgLang->isRTL() ? 'right' : 'left';
$s .= "<td class='bottom' align='$l' valign='top'>";
$s .= $this->bottomLinks();
$s .= "\n<br />" . $this->mainPageLink()
- . " | " . $this->aboutLink()
- . " | " . $this->specialLink( "recentchanges" )
- . " | " . $this->searchForm()
- . "<br /><span id='pagestats'>" . $this->pageStats() . "</span>";
+ . ' | ' . $this->aboutLink()
+ . ' | ' . $this->specialLink( 'recentchanges' )
+ . ' | ' . $this->searchForm()
+ . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
$s .= "</td>";
if ( $shove && !$left ) { # Right
@@ -435,10 +480,10 @@ class Skin {
}
$s .= "</tr></table>\n</div>\n</div>\n";
- wfProfileOut( "$fname-3" );
- wfProfileIn( "$fname-4" );
+ wfProfileOut( $fname.'-3' );
+ wfProfileIn( $fname.'-4' );
if ( 0 != $qb ) { $s .= $this->quickBar(); }
- wfProfileOut( "$fname-4" );
+ wfProfileOut( $fname.'-4' );
wfProfileOut( $fname );
return $s;
}
@@ -451,7 +496,7 @@ class Skin {
$action = $wgRequest->getText( 'action' );
$s = $this->printableLink();
- if ( wfMsg ( "disclaimers" ) != "-" ) $s .= " | " . $this->makeKnownLink( wfMsg( "disclaimerpage" ), wfMsg( "disclaimers" ) ) ;
+ if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
if ( $wgOut->isArticleRelated() ) {
if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
@@ -464,16 +509,16 @@ class Skin {
if ( isset ( $wgUseApproval ) && $wgUseApproval )
{
$t = $wgTitle->getDBkey();
- $name = "Approve this article" ;
+ $name = 'Approve this article' ;
$link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
#wfEscapeHTML( wfImageUrl( $name ) );
$style = $this->getExternalLinkAttributes( $link, $name );
$s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
}
}
- if ( "history" == $action || isset( $diff ) || isset( $oldid ) ) {
- $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
- wfMsg( "currentrev" ) );
+ if ( 'history' == $action || isset( $diff ) || isset( $oldid ) ) {
+ $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
+ wfMsg( 'currentrev' ) );
}
if ( $wgUser->getNewtalk() ) {
@@ -485,35 +530,45 @@ class Skin {
$n =$wgUser->getName();
$tl = $this->makeKnownLink( $wgLang->getNsText(
Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
- wfMsg("newmessageslink") );
- $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
+ wfMsg('newmessageslink') );
+ $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
}
}
- if( $wgUser->isSysop() &&
- (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
- ($n = $wgTitle->isDeleted() ) ) {
- $s .= " | " . wfMsg( "thisisdeleted",
- $this->makeKnownLink(
- $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
- wfMsg( "restorelink", $n ) ) );
+
+ $undelete = $this->getUndeleteLink();
+ if( !empty( $undelete ) ) {
+ $s .= ' | '.$undelete;
}
return $s;
}
+ function getUndeleteLink() {
+ global $wgUser, $wgTitle, $wgLang, $action;
+ if( $wgUser->isSysop() &&
+ (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
+ ($n = $wgTitle->isDeleted() ) ) {
+ return wfMsg( 'thisisdeleted',
+ $this->makeKnownLink(
+ $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
+ wfMsg( 'restorelink', $n ) ) );
+ }
+ return '';
+ }
+
function printableLink()
{
global $wgOut, $wgFeedClasses, $wgRequest;
$baseurl = $_SERVER['REQUEST_URI'];
- if( strpos( "?", $baseurl ) == false ) {
- $baseurl .= "?";
+ if( strpos( '?', $baseurl ) == false ) {
+ $baseurl .= '?';
} else {
- $baseurl .= "&";
+ $baseurl .= '&';
}
$baseurl = htmlspecialchars( $baseurl );
- $printurl = $wgRequest->escapeAppendQuery( "printable=yes" );
+ $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
- $s = "<a href=\"$printurl\">" . wfMsg( "printableversion" ) . "</a>";
+ $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
if( $wgOut->isSyndicated() ) {
foreach( $wgFeedClasses as $format => $class ) {
$feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
@@ -527,8 +582,8 @@ class Skin {
{
global $wgOut, $wgTitle, $wgUser;
- $s = "<h1 class='pagetitle'>" . htmlspecialchars( $wgOut->getPageTitle() ) . "</h1>";
- if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
+ $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
+ if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
return $s;
}
@@ -537,9 +592,9 @@ class Skin {
global $wgOut;
$sub = $wgOut->getSubtitle();
- if ( "" == $sub ) {
+ if ( '' == $sub ) {
global $wgExtraSubtitle;
- $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
+ $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
}
$subpages = $this->subPageSubtitle();
$sub .= !empty($subpages)?"</p><p class='subpages'>$subpages":'';
@@ -553,23 +608,23 @@ class Skin {
$subpages = '';
if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
$ptext=$wgTitle->getPrefixedText();
- if(preg_match("/\//",$ptext)) {
- $links=explode("/",$ptext);
- $c=0;
- $growinglink="";
+ if(preg_match('/\//',$ptext)) {
+ $links = explode('/',$ptext);
+ $c = 0;
+ $growinglink = '';
foreach($links as $link) {
$c++;
if ($c<count($links)) {
$growinglink .= $link;
$getlink = $this->makeLink( $growinglink, $link );
- if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
+ if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
if ($c>1) {
- $subpages .= " | ";
+ $subpages .= ' | ';
} else {
- $subpages .="&lt; ";
+ $subpages .= '&lt; ';
}
$subpages .= $getlink;
- $growinglink.="/";
+ $growinglink .= '/';
}
}
}
@@ -581,30 +636,30 @@ class Skin {
{
global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
- $li = $wgLang->specialPage( "Userlogin" );
- $lo = $wgLang->specialPage( "Userlogout" );
+ $li = $wgLang->specialPage( 'Userlogin' );
+ $lo = $wgLang->specialPage( 'Userlogout' );
- $s = "";
+ $s = '';
if ( 0 == $wgUser->getID() ) {
- if( $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] ) ) {
+ if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
$n = $wgIP;
$tl = $this->makeKnownLink( $wgLang->getNsText(
Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
$wgLang->getNsText( Namespace::getTalk( 0 ) ) );
- $s .= $n . " (".$tl.")";
+ $s .= $n . ' ('.$tl.')';
} else {
- $s .= wfMsg("notloggedin");
+ $s .= wfMsg('notloggedin');
}
$rt = $wgTitle->getPrefixedURL();
if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
- $q = "";
+ $q = '';
} else { $q = "returnto={$rt}"; }
$s .= "\n<br />" . $this->makeKnownLink( $li,
- wfMsg( "login" ), $q );
+ wfMsg( 'login' ), $q );
} else {
$n = $wgUser->getName();
$rt = $wgTitle->getPrefixedURL();
@@ -616,18 +671,18 @@ class Skin {
$s .= $this->makeKnownLink( $wgLang->getNsText(
Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
- $this->makeKnownLink( $lo, wfMsg( "logout" ),
- "returnto={$rt}" ) . " | " .
- $this->specialLink( "preferences" );
+ $this->makeKnownLink( $lo, wfMsg( 'logout' ),
+ "returnto={$rt}" ) . ' | ' .
+ $this->specialLink( 'preferences' );
}
- $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
- wfMsg( "help" ) );
+ $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
+ wfMsg( 'help' ) );
return $s;
}
function getSearchLink() {
- $searchPage =& Title::makeTitle( NS_SPECIAL, "Search" );
+ $searchPage =& Title::makeTitle( NS_SPECIAL, 'Search' );
return $searchPage->getLocalURL();
}
@@ -640,12 +695,12 @@ class Skin {
global $wgRequest;
$search = $wgRequest->getText( 'search' );
- $s = "<form name='search' class='inline' method='post' action=\""
+ $s = '<form name="search" class="inline" method="post" action="'
. $this->escapeSearchLink() . "\">\n"
- . "<input type='text' name=\"search\" size='19' value=\""
+ . '<input type="text" name="search" size="19" value="'
. htmlspecialchars(substr($search,0,256)) . "\" />\n"
- . "<input type='submit' name=\"go\" value=\"" . wfMsg ("go") . "\" />&nbsp;"
- . "<input type='submit' name=\"fulltext\" value=\"" . wfMsg ("search") . "\" />\n</form>";
+ . '<input type="submit" name="go" value="' . wfMsg ('go') . '" />&nbsp;'
+ . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
return $s;
}
@@ -656,7 +711,7 @@ class Skin {
$sep = " |\n";
$s = $this->mainPageLink() . $sep
- . $this->specialLink( "recentchanges" );
+ . $this->specialLink( 'recentchanges' );
if ( $wgOut->isArticleRelated() ) {
$s .= $sep . $this->editThisPage()
@@ -673,9 +728,9 @@ class Skin {
global $wgOut, $wgUser, $wgTitle;
$sep = " |\n";
- $s = "";
+ $s = '';
if ( $wgOut->isArticleRelated() ) {
- $s .= "<strong>" . $this->editThisPage() . "</strong>";
+ $s .= '<strong>' . $this->editThisPage() . '</strong>';
if ( 0 != $wgUser->getID() ) {
$s .= $sep . $this->watchThisPage();
}
@@ -716,21 +771,21 @@ class Skin {
global $wgDisableCounters;
extract( $wgRequest->getValues( 'oldid', 'diff' ) );
- if ( ! $wgOut->isArticle() ) { return ""; }
- if ( isset( $oldid ) || isset( $diff ) ) { return ""; }
- if ( 0 == $wgArticle->getID() ) { return ""; }
+ if ( ! $wgOut->isArticle() ) { return ''; }
+ if ( isset( $oldid ) || isset( $diff ) ) { return ''; }
+ if ( 0 == $wgArticle->getID() ) { return ''; }
- $s = "";
+ $s = '';
if ( !$wgDisableCounters ) {
$count = $wgLang->formatNum( $wgArticle->getCount() );
if ( $count ) {
- $s = wfMsg( "viewcount", $count );
+ $s = wfMsg( 'viewcount', $count );
}
}
- $s .= " " . $this->getCredits();
+ $s .= ' ' . $this->getCredits();
- return $s . " " . $this->getCopyright();
+ return $s . ' ' . $this->getCopyright();
}
function getCredits() {
@@ -743,7 +798,7 @@ class Skin {
} else {
$s = $this->getAuthorCredits();
if ($wgMaxCredits > 1) {
- $s .= " " . $this->getContributorCredits();
+ $s .= ' ' . $this->getContributorCredits();
}
}
@@ -756,13 +811,13 @@ class Skin {
$last_author = $wgArticle->getUser();
if ($last_author == 0) {
- $author_credit = wfMsg("anonymous");
+ $author_credit = wfMsg('anonymous');
} else {
$real_name = User::whoIsReal($last_author);
if (!empty($real_name)) {
$author_credit = $real_name;
} else {
- $author_credit = wfMsg("siteuser", User::whoIs($last_author));
+ $author_credit = wfMsg('siteuser', User::whoIs($last_author));
}
}
@@ -770,9 +825,9 @@ class Skin {
if ( $timestamp ) {
$d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
} else {
- $d = "";
+ $d = '';
}
- return wfMsg("lastmodifiedby", $d, $author_credit);
+ return wfMsg('lastmodifiedby', $d, $author_credit);
}
function getContributorCredits() {
@@ -802,23 +857,34 @@ class Skin {
$user = $wgLang->listToText(array_values($user_names));
if (!empty($user)) {
- $user = wfMsg("siteusers", $user);
+ $user = wfMsg('siteusers', $user);
}
if ($contributors[0] && $contributors[0][0] > 0) {
- $anon = wfMsg("anonymous");
+ $anon = wfMsg('anonymous');
} else {
$anon = '';
}
$creds = $wgLang->listToText(array($real, $user, $anon));
- return wfMsg("othercontribs", $creds);
+ return wfMsg('othercontribs', $creds);
}
function getCopyright() {
- global $wgRightsPage, $wgRightsUrl, $wgRightsText;
- $out = "";
+ global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
+
+
+ $oldid = $wgRequest->getVal( 'oldid' );
+ $diff = $wgRequest->getVal( 'diff' );
+
+ if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
+ $msg = 'history_copyright';
+ } else {
+ $msg = 'copyright';
+ }
+
+ $out = '';
if( $wgRightsPage ) {
$link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
} elseif( $wgRightsUrl ) {
@@ -827,23 +893,23 @@ class Skin {
# Give up now
return $out;
}
- $out .= wfMsg( "copyright", $link );
+ $out .= wfMsg( $msg, $link );
return $out;
}
function getCopyrightIcon() {
global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
- $out = "";
+ $out = '';
if( $wgRightsIcon ) {
$icon = htmlspecialchars( $wgRightsIcon );
if( $wgRightsUrl ) {
$url = htmlspecialchars( $wgRightsUrl );
- $out .= "<a href=\"$url\">";
+ $out .= '<a href="'.$url.'">';
}
$text = htmlspecialchars( $wgRightsText );
$out .= "<img src=\"$icon\" alt='$text' />";
if( $wgRightsUrl ) {
- $out .= "</a>";
+ $out .= '</a>';
}
}
return $out;
@@ -852,7 +918,7 @@ class Skin {
function getPoweredBy() {
global $wgStylePath;
$url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
- $img = "<a href='http://www.mediawiki.org/'><img src='$url' alt='MediaWiki' /></a>";
+ $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
return $img;
}
@@ -863,23 +929,23 @@ class Skin {
$timestamp = $wgArticle->getTimestamp();
if ( $timestamp ) {
$d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
- $s = " " . wfMsg( "lastmodified", $d );
+ $s = ' ' . wfMsg( 'lastmodified', $d );
} else {
- $s = "";
+ $s = '';
}
return $s;
}
- function logoText( $align = "" )
+ function logoText( $align = '' )
{
- if ( "" != $align ) { $a = " align='{$align}'"; }
- else { $a = ""; }
+ if ( '' != $align ) { $a = ' align="'.$align.'"'; }
+ else { $a = ''; }
- $mp = wfMsg( "mainpage" );
+ $mp = wfMsg( 'mainpage' );
$titleObj = Title::newFromText( $mp );
- $s = "<a href=\"" . $titleObj->escapeLocalURL()
- . "\"><img{$a} src=\""
- . $this->getLogo() . "\" alt=\"" . "[{$mp}]\" /></a>";
+ $s = '<a href="' . $titleObj->escapeLocalURL()
+ . '"><img'.$a.' src="'
+ . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
return $s;
}
@@ -888,7 +954,7 @@ class Skin {
global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
global $wgDisableUploads, $wgRemoteUploads;
- $fname = "Skin::quickBar";
+ $fname = 'Skin::quickBar';
wfProfileIn( $fname );
$action = $wgRequest->getText( 'action' );
@@ -900,69 +966,69 @@ class Skin {
$sep = "\n<br />";
$s .= $this->mainPageLink()
- . $sep . $this->specialLink( "recentchanges" )
- . $sep . $this->specialLink( "randompage" );
+ . $sep . $this->specialLink( 'recentchanges' )
+ . $sep . $this->specialLink( 'randompage' );
if ($wgUser->getID()) {
- $s.= $sep . $this->specialLink( "watchlist" ) ;
- $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
- wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
+ $s.= $sep . $this->specialLink( 'watchlist' ) ;
+ $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
+ wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
}
// only show watchlist link if logged in
- if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
+ if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
$s .= "\n<br /><hr class='sep' />";
$articleExists = $wgTitle->getArticleId();
- if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
+ if ( $wgOut->isArticle() || $action =='edit' || $action =='history' || $wpPreview) {
if($wgOut->isArticle()) {
- $s .= "<strong>" . $this->editThisPage() . "</strong>";
+ $s .= '<strong>' . $this->editThisPage() . '</strong>';
} else { # backlink to the article in edit or history mode
if($articleExists){ # no backlink if no article
switch($tns) {
case 0:
- $text = wfMsg("articlepage");
+ $text = wfMsg('articlepage');
break;
case 1:
- $text = wfMsg("viewtalkpage");
+ $text = wfMsg('viewtalkpage');
break;
case 2:
- $text = wfMsg("userpage");
+ $text = wfMsg('userpage');
break;
case 3:
- $text = wfMsg("viewtalkpage");
+ $text = wfMsg('viewtalkpage');
break;
case 4:
- $text = wfMsg("wikipediapage");
+ $text = wfMsg('wikipediapage');
break;
case 5:
- $text = wfMsg("viewtalkpage");
+ $text = wfMsg('viewtalkpage');
break;
case 6:
- $text = wfMsg("imagepage");
+ $text = wfMsg('imagepage');
break;
case 7:
- $text = wfMsg("viewtalkpage");
+ $text = wfMsg('viewtalkpage');
break;
default:
- $text= wfMsg("articlepage");
+ $text= wfMsg('articlepage');
}
$link = $wgTitle->getText();
if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
- $link = $nstext . ":" . $link ;
+ $link = $nstext . ':' . $link ;
}
$s .= $this->makeLink( $link, $text );
} elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
# we just throw in a "New page" text to tell the user that he's in edit mode,
# and to avoid messing with the separator that is prepended to the next item
- $s .= "<strong>" . wfMsg("newpage") . "</strong>";
+ $s .= '<strong>' . wfMsg('newpage') . '</strong>';
}
}
- if( $tns%2 && $action!="edit" && !$wpPreview) {
- $s.="<br />".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
+ if( $tns%2 && $action!='edit' && !$wpPreview) {
+ $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit&section=new');
}
/*
@@ -972,7 +1038,7 @@ class Skin {
unwatched. Therefore we do not show the "Watch this page" link in edit mode
*/
if ( 0 != $wgUser->getID() && $articleExists) {
- if($action!="edit" && $action != "submit" )
+ if($action!='edit' && $action != 'submit' )
{
$s .= $sep . $this->watchThisPage();
}
@@ -984,7 +1050,7 @@ class Skin {
$sep . $this->protectThisPage();
}
$s .= $sep . $this->talkLink();
- if ($articleExists && $action !="history") {
+ if ($articleExists && $action !='history') {
$s .= $sep . $this->historyLink();
}
$s.=$sep . $this->whatLinksHere();
@@ -1013,15 +1079,15 @@ class Skin {
}
if ( 0 != $wgUser->getID() && ( !$wgDisableUploads || $wgRemoteUploads ) ) {
- $s .= $this->specialLink( "upload" ) . $sep;
+ $s .= $this->specialLink( 'upload' ) . $sep;
}
- $s .= $this->specialLink( "specialpages" )
+ $s .= $this->specialLink( 'specialpages' )
. $sep . $this->bugReportsLink();
global $wgSiteSupportPage;
if( $wgSiteSupportPage ) {
$s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
- "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
+ '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
}
$s .= "\n<br /></div>\n";
@@ -1032,30 +1098,31 @@ class Skin {
function specialPagesList()
{
global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
+ require_once('SpecialPage.php');
$a = array();
$pages = SpecialPage::getPages();
- foreach ( $pages[""] as $name => $page ) {
+ foreach ( $pages[''] as $name => $page ) {
$a[$name] = $page->getDescription();
}
if ( $wgUser->isSysop() )
{
- foreach ( $pages["sysop"] as $name => $page ) {
+ foreach ( $pages['sysop'] as $name => $page ) {
$a[$name] = $page->getDescription();
}
}
if ( $wgUser->isDeveloper() )
{
- foreach ( $pages["developer"] as $name => $page ) {
+ foreach ( $pages['developer'] as $name => $page ) {
$a[$name] = $page->getDescription() ;
}
}
- $go = wfMsg( "go" );
- $sp = wfMsg( "specialpages" );
- $spp = $wgLang->specialPage( "Specialpages" );
+ $go = wfMsg( 'go' );
+ $sp = wfMsg( 'specialpages' );
+ $spp = $wgLang->specialPage( 'Specialpages' );
- $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
- "action=\"" . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
+ $s = '<form id="specialpages" method="get" class="inline" ' .
+ 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
$s .= "<select name=\"wpDropdown\">\n";
$s .= "<option value=\"{$spp}\">{$sp}</option>\n";
@@ -1071,30 +1138,30 @@ class Skin {
function mainPageLink()
{
- $mp = wfMsg( "mainpage" );
+ $mp = wfMsg( 'mainpage' );
$s = $this->makeKnownLink( $mp, $mp );
return $s;
}
function copyrightLink()
{
- $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
- wfMsg( "copyrightpagename" ) );
+ $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
+ wfMsg( 'copyrightpagename' ) );
return $s;
}
function aboutLink()
{
- $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
- wfMsg( "aboutwikipedia" ) );
+ $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
+ wfMsg( 'aboutwikipedia' ) );
return $s;
}
function disclaimerLink()
{
- $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
- wfMsg( "disclaimers" ) );
+ $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
+ wfMsg( 'disclaimers' ) );
return $s;
}
@@ -1107,16 +1174,16 @@ class Skin {
$redirect = $wgRequest->getVal( 'redirect' );
if ( ! $wgOut->isArticleRelated() ) {
- $s = wfMsg( "protectedpage" );
+ $s = wfMsg( 'protectedpage' );
} else {
$n = $wgTitle->getPrefixedText();
if ( $wgTitle->userCanEdit() ) {
- $t = wfMsg( "editthispage" );
+ $t = wfMsg( 'editthispage' );
} else {
#$t = wfMsg( "protectedpage" );
- $t = wfMsg( "viewsource" );
+ $t = wfMsg( 'viewsource' );
}
- $oid = $red = "";
+ $oid = $red = '';
if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
if ( $oldid && ! isset( $diff ) ) {
@@ -1134,11 +1201,11 @@ class Skin {
$diff = $wgRequest->getVal( 'diff' );
if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
$n = $wgTitle->getPrefixedText();
- $t = wfMsg( "deletethispage" );
+ $t = wfMsg( 'deletethispage' );
- $s = $this->makeKnownLink( $n, $t, "action=delete" );
+ $s = $this->makeKnownLink( $n, $t, 'action=delete' );
} else {
- $s = "";
+ $s = '';
}
return $s;
}
@@ -1152,15 +1219,15 @@ class Skin {
$n = $wgTitle->getPrefixedText();
if ( $wgTitle->isProtected() ) {
- $t = wfMsg( "unprotectthispage" );
- $q = "action=unprotect";
+ $t = wfMsg( 'unprotectthispage' );
+ $q = 'action=unprotect';
} else {
- $t = wfMsg( "protectthispage" );
- $q = "action=protect";
+ $t = wfMsg( 'protectthispage' );
+ $q = 'action=protect';
}
$s = $this->makeKnownLink( $n, $t, $q );
} else {
- $s = "";
+ $s = '';
}
return $s;
}
@@ -1173,15 +1240,15 @@ class Skin {
$n = $wgTitle->getPrefixedText();
if ( $wgTitle->userIsWatching() ) {
- $t = wfMsg( "unwatchthispage" );
- $q = "action=unwatch";
+ $t = wfMsg( 'unwatchthispage' );
+ $q = 'action=unwatch';
} else {
- $t = wfMsg( "watchthispage" );
- $q = "action=watch";
+ $t = wfMsg( 'watchthispage' );
+ $q = 'action=watch';
}
$s = $this->makeKnownLink( $n, $t, $q );
} else {
- $s = wfMsg( "notanarticle" );
+ $s = wfMsg( 'notanarticle' );
}
return $s;
}
@@ -1191,8 +1258,8 @@ class Skin {
global $wgTitle, $wgLang;
if ( $wgTitle->userCanEdit() ) {
- $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
- wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
+ $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
+ wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
} // no message if page is protected - would be redundant
return $s;
}
@@ -1202,7 +1269,7 @@ class Skin {
global $wgTitle;
$s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
- wfMsg( "history" ), "action=history" );
+ wfMsg( 'history' ), 'action=history' );
return $s;
}
@@ -1210,8 +1277,8 @@ class Skin {
{
global $wgTitle, $wgLang;
- $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
- wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
+ $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
+ wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
return $s;
}
@@ -1219,8 +1286,8 @@ class Skin {
{
global $wgTitle, $wgLang;
- $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
- wfMsg( "contributions" ), "target=" . $wgTitle->getPartialURL() );
+ $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
+ wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
return $s;
}
@@ -1228,8 +1295,8 @@ class Skin {
{
global $wgTitle, $wgLang;
- $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
- wfMsg( "emailuser" ), "target=" . $wgTitle->getPartialURL() );
+ $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
+ wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
return $s;
}
@@ -1238,11 +1305,11 @@ class Skin {
global $wgOut, $wgTitle, $wgLang;
if ( ! $wgOut->isArticleRelated() ) {
- $s = "(" . wfMsg( "notanarticle" ) . ")";
+ $s = '(' . wfMsg( 'notanarticle' ) . ')';
} else {
$s = $this->makeKnownLink( $wgLang->specialPage(
- "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
- "target=" . $wgTitle->getPrefixedURL() );
+ 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
+ 'target=' . $wgTitle->getPrefixedURL() );
}
return $s;
}
@@ -1253,56 +1320,56 @@ class Skin {
$a = $wgOut->getLanguageLinks();
if ( 0 == count( $a ) ) {
- if ( !$wgUseNewInterlanguage ) return "";
+ if ( !$wgUseNewInterlanguage ) return '';
$ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
- if ( $ns != 0 AND $ns != 1 ) return "" ;
- $pn = "Intl" ;
- $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
+ if ( $ns != 0 AND $ns != 1 ) return '' ;
+ $pn = 'Intl' ;
+ $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
return $this->makeKnownLink( $wgLang->specialPage( $pn ),
- wfMsg( "intl" ) , $x );
+ wfMsg( 'intl' ) , $x );
}
if ( !$wgUseNewInterlanguage ) {
- $s = wfMsg( "otherlanguages" ) . ": ";
+ $s = wfMsg( 'otherlanguages' ) . ': ';
} else {
global $wgLanguageCode ;
- $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
- $x .= "&xl=".$wgLanguageCode ;
- $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
- wfMsg( "otherlanguages" ) , $x ) . ": " ;
+ $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
+ $x .= '&xl='.$wgLanguageCode ;
+ $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
+ wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
}
- $s = wfMsg( "otherlanguages" ) . ": ";
+ $s = wfMsg( 'otherlanguages' ) . ': ';
$first = true;
- if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
+ if($wgLang->isRTL()) $s .= '<span dir="LTR">';
foreach( $a as $l ) {
- if ( ! $first ) { $s .= " | "; }
+ if ( ! $first ) { $s .= ' | '; }
$first = false;
$nt = Title::newFromText( $l );
$url = $nt->getFullURL();
$text = $wgLang->getLanguageName( $nt->getInterwiki() );
- if ( "" == $text ) { $text = $l; }
+ if ( '' == $text ) { $text = $l; }
$style = $this->getExternalLinkAttributes( $l, $text );
$s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
}
- if($wgLang->isRTL()) $s .= "</span>";
+ if($wgLang->isRTL()) $s .= '</span>';
return $s;
}
function bugReportsLink()
{
- $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
- wfMsg( "bugreports" ) );
+ $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
+ wfMsg( 'bugreports' ) );
return $s;
}
function dateLink()
{
global $wgLinkCache;
- $t1 = Title::newFromText( gmdate( "F j" ) );
- $t2 = Title::newFromText( gmdate( "Y" ) );
+ $t1 = Title::newFromText( gmdate( 'F j' ) );
+ $t2 = Title::newFromText( gmdate( 'Y' ) );
$wgLinkCache->suspend();
$id = $t1->getArticleID();
@@ -1313,7 +1380,7 @@ class Skin {
} else {
$s = $this->makeKnownLink( $t1->getText() );
}
- $s .= ", ";
+ $s .= ', ';
$wgLinkCache->suspend();
$id = $t2->getArticleID();
@@ -1332,27 +1399,27 @@ class Skin {
global $wgLang, $wgTitle, $wgLinkCache;
$tns = $wgTitle->getNamespace();
- if ( -1 == $tns ) { return ""; }
+ if ( -1 == $tns ) { return ''; }
$pn = $wgTitle->getText();
- $tp = wfMsg( "talkpage" );
+ $tp = wfMsg( 'talkpage' );
if ( Namespace::isTalk( $tns ) ) {
$lns = Namespace::getSubject( $tns );
switch($tns) {
case 1:
- $text = wfMsg("articlepage");
+ $text = wfMsg('articlepage');
break;
case 3:
- $text = wfMsg("userpage");
+ $text = wfMsg('userpage');
break;
case 5:
- $text = wfMsg("wikipediapage");
+ $text = wfMsg('wikipediapage');
break;
case 7:
- $text = wfMsg("imagepage");
+ $text = wfMsg('imagepage');
break;
default:
- $text= wfMsg("articlepage");
+ $text= wfMsg('articlepage');
}
} else {
@@ -1360,8 +1427,8 @@ class Skin {
$text=$tp;
}
$n = $wgLang->getNsText( $lns );
- if ( "" == $n ) { $link = $pn; }
- else { $link = "{$n}:{$pn}"; }
+ if ( '' == $n ) { $link = $pn; }
+ else { $link = $n.':'.$pn; }
$wgLinkCache->suspend();
$s = $this->makeLink( $link, $text );
@@ -1375,7 +1442,7 @@ class Skin {
global $wgLang, $wgTitle, $wgLinkCache;
$tns = $wgTitle->getNamespace();
- if ( -1 == $tns ) { return ""; }
+ if ( -1 == $tns ) { return ''; }
$lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
@@ -1384,10 +1451,10 @@ class Skin {
$n = $wgLang->getNsText( $lns );
$pn = $wgTitle->getText();
- $link = "{$n}:{$pn}";
+ $link = $n.':'.$pn;
$wgLinkCache->suspend();
- $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit&section=new");
+ $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit&section=new');
$wgLinkCache->resume();
return $s;
@@ -1404,63 +1471,63 @@ class Skin {
# Note: This function MUST call getArticleID() on the link,
# otherwise the cache won't get updated properly. See LINKCACHE.DOC.
#
- function makeLink( $title, $text = "", $query = "", $trail = "" ) {
- wfProfileIn( "Skin::makeLink" );
+ function makeLink( $title, $text = '', $query = '', $trail = '' ) {
+ wfProfileIn( 'Skin::makeLink' );
$nt = Title::newFromText( $title );
if ($nt) {
$result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
} else {
- wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
+ wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
$result = $text == "" ? $title : $text;
}
- wfProfileOut( "Skin::makeLink" );
+ wfProfileOut( 'Skin::makeLink' );
return $result;
}
- function makeKnownLink( $title, $text = "", $query = "", $trail = "", $prefix = '',$aprops = '') {
+ function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
$nt = Title::newFromText( $title );
if ($nt) {
return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
} else {
- wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
- return $text == "" ? $title : $text;
+ wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
+ return $text == '' ? $title : $text;
}
}
- function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
+ function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
$nt = Title::newFromText( $title );
if ($nt) {
return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
} else {
- wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
- return $text == "" ? $title : $text;
+ wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
+ return $text == '' ? $title : $text;
}
}
- function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
+ function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
$nt = Title::newFromText( $title );
if ($nt) {
return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
} else {
- wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
- return $text == "" ? $title : $text;
+ wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
+ return $text == '' ? $title : $text;
}
}
# Pass a title object, not a title string
- function makeLinkObj( &$nt, $text= "", $query = "", $trail = "", $prefix = "" )
+ function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
{
global $wgOut, $wgUser;
if ( $nt->isExternal() ) {
$u = $nt->getFullURL();
$link = $nt->getPrefixedURL();
- if ( "" == $text ) { $text = $nt->getPrefixedText(); }
- $style = $this->getExternalLinkAttributes( $link, $text );
+ if ( '' == $text ) { $text = $nt->getPrefixedText(); }
+ $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
- $inside = "";
- if ( "" != $trail ) {
- if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
+ $inside = '';
+ if ( '' != $trail ) {
+ if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
$inside = $m[1];
$trail = $m[2];
}
@@ -1476,7 +1543,7 @@ class Skin {
if ( 0 == $aid ) {
$retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
} else {
- $threshold = $wgUser->getOption("stubthreshold") ;
+ $threshold = $wgUser->getOption('stubthreshold') ;
if ( $threshold > 0 ) {
$res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
@@ -1504,33 +1571,41 @@ class Skin {
}
# Pass a title object, not a title string
- function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" , $aprops = '')
+ function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
{
- global $wgOut, $wgTitle;
+ global $wgOut, $wgTitle, $wgInputEncoding;
- $fname = "Skin::makeKnownLinkObj";
+ $fname = 'Skin::makeKnownLinkObj';
wfProfileIn( $fname );
+ if ( !is_object( $nt ) ) {
+ return $text;
+ }
$link = $nt->getPrefixedURL();
- if ( "" == $link ) {
- $u = "";
- if ( "" == $text ) {
+ if ( '' == $link ) {
+ $u = '';
+ if ( '' == $text ) {
$text = htmlspecialchars( $nt->getFragment() );
}
} else {
$u = $nt->escapeLocalURL( $query );
}
- if ( "" != $nt->getFragment() ) {
- $u .= "#" . htmlspecialchars( $nt->getFragment() );
+ if ( '' != $nt->getFragment() ) {
+ $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT, $wgInputEncoding ) );
+ $replacearray = array(
+ '%3A' => ':',
+ '%' => '.'
+ );
+ $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
}
- if ( "" == $text ) {
+ if ( '' == $text ) {
$text = htmlspecialchars( $nt->getPrefixedText() );
}
$style = $this->getInternalLinkAttributesObj( $nt, $text );
- $inside = "";
- if ( "" != $trail ) {
+ $inside = '';
+ if ( '' != $trail ) {
if ( preg_match( $this->linktrail, $trail, $m ) ) {
$inside = $m[1];
$trail = $m[2];
@@ -1542,33 +1617,33 @@ class Skin {
}
# Pass a title object, not a title string
- function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
+ function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
{
global $wgOut, $wgUser;
- $fname = "Skin::makeBrokenLinkObj";
+ $fname = 'Skin::makeBrokenLinkObj';
wfProfileIn( $fname );
- if ( "" == $query ) {
- $q = "action=edit";
+ if ( '' == $query ) {
+ $q = 'action=edit';
} else {
- $q = "action=edit&{$query}";
+ $q = 'action=edit&'.$query;
}
$u = $nt->escapeLocalURL( $q );
- if ( "" == $text ) {
+ if ( '' == $text ) {
$text = htmlspecialchars( $nt->getPrefixedText() );
}
$style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
- $inside = "";
- if ( "" != $trail ) {
+ $inside = '';
+ if ( '' != $trail ) {
if ( preg_match( $this->linktrail, $trail, $m ) ) {
$inside = $m[1];
$trail = $m[2];
}
}
- if ( $wgUser->getOption( "highlightbroken" ) ) {
+ if ( $wgUser->getOption( 'highlightbroken' ) ) {
$s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
} else {
$s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
@@ -1579,7 +1654,7 @@ class Skin {
}
# Pass a title object, not a title string
- function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
+ function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
{
global $wgOut, $wgUser;
@@ -1587,19 +1662,19 @@ class Skin {
$u = $nt->escapeLocalURL( $query );
- if ( "" == $text ) {
+ if ( '' == $text ) {
$text = htmlspecialchars( $nt->getPrefixedText() );
}
- $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
+ $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
- $inside = "";
- if ( "" != $trail ) {
+ $inside = '';
+ if ( '' != $trail ) {
if ( preg_match( $this->linktrail, $trail, $m ) ) {
$inside = $m[1];
$trail = $m[2];
}
}
- if ( $wgUser->getOption( "highlightbroken" ) ) {
+ if ( $wgUser->getOption( 'highlightbroken' ) ) {
$s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
} else {
$s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
@@ -1607,14 +1682,14 @@ class Skin {
return $s;
}
- function makeSelfLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
+ function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
{
$u = $nt->escapeLocalURL( $query );
- if ( "" == $text ) {
+ if ( '' == $text ) {
$text = htmlspecialchars( $nt->getPrefixedText() );
}
- $inside = "";
- if ( "" != $trail ) {
+ $inside = '';
+ if ( '' != $trail ) {
if ( preg_match( $this->linktrail, $trail, $m ) ) {
$inside = $m[1];
$trail = $m[2];
@@ -1651,6 +1726,12 @@ class Skin {
$this->checkTitle($title, $name);
return $title->getLocalURL( $urlaction );
}
+ # this can be passed the NS number as defined in Language.php
+ /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
+ $title = Title::makeTitle( $namespace, $name );
+ $this->checkTitle($title, $name);
+ return $title->getLocalURL( $urlaction );
+ }
/* these return an array with the 'href' and boolean 'exists' */
/*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
@@ -1693,40 +1774,40 @@ class Skin {
if(!is_object($title)) {
$title = Title::newFromText( $name );
if(!is_object($title)) {
- $title = Title::newFromText( '<error: link target missing>' );
+ $title = Title::newFromText( '--error: link target missing--' );
}
}
}
function fnamePart( $url )
{
- $basename = strrchr( $url, "/" );
+ $basename = strrchr( $url, '/' );
if ( false === $basename ) { $basename = $url; }
else { $basename = substr( $basename, 1 ); }
return wfEscapeHTML( $basename );
}
- function makeImage( $url, $alt = "" )
+ function makeImage( $url, $alt = '' )
{
global $wgOut;
- if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
- $s = "<img src=\"{$url}\" alt=\"{$alt}\" />";
+ if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
+ $s = '<img src="'.$url.'" alt="'.$alt.'" />';
return $s;
}
- function makeImageLink( $name, $url, $alt = "" ) {
+ function makeImageLink( $name, $url, $alt = '' ) {
$nt = Title::makeTitle( Namespace::getImage(), $name );
return $this->makeImageLinkObj( $nt, $alt );
}
- function makeImageLinkObj( $nt, $alt = "" ) {
+ function makeImageLinkObj( $nt, $alt = '' ) {
global $wgLang, $wgUseImageResize;
$img = Image::newFromTitle( $nt );
$url = $img->getURL();
- $align = "";
- $prefix = $postfix = "";
+ $align = '';
+ $prefix = $postfix = '';
if ( $wgUseImageResize ) {
# Check if the alt text is of the form "options|alt text"
@@ -1739,7 +1820,7 @@ class Skin {
# * center center the image
# * framed Keep original image size, no magnify-button.
- $part = explode( "|", $alt);
+ $part = explode( '|', $alt);
$mwThumb =& MagicWord::get( MAG_IMG_THUMBNAIL );
$mwLeft =& MagicWord::get( MAG_IMG_LEFT );
@@ -1757,19 +1838,19 @@ class Skin {
$thumb=true;
} elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
# remember to set an alignment, don't render immediately
- $align = "right";
+ $align = 'right';
} elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
# remember to set an alignment, don't render immediately
- $align = "left";
+ $align = 'left';
} elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
# remember to set an alignment, don't render immediately
- $align = "center";
+ $align = 'center';
} elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
# remember to set an alignment, don't render immediately
- $align = "none";
+ $align = 'none';
} elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
# $match is the image width in pixels
- if ( preg_match( "/^([0-9]*)x([0-9]*)$/", $match, $m ) ) {
+ if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
$width = intval( $m[1] );
$height = intval( $m[2] );
} else {
@@ -1779,11 +1860,11 @@ class Skin {
$framed=true;
}
}
- if ( "center" == $align )
+ if ( 'center' == $align )
{
$prefix = '<span style="text-align: center">';
$postfix = '</span>';
- $align = "none";
+ $align = 'none';
}
if ( $thumb || $framed ) {
@@ -1795,8 +1876,8 @@ class Skin {
#
# If thumbnail width has not been provided, it is set
# here to 180 pixels
- if ( $align == "" ) {
- $align = $wgLang->isRTL() ? "left" : "right";
+ if ( $align == '' ) {
+ $align = $wgLang->isRTL() ? 'left' : 'right';
}
if ( ! isset($width) ) {
$width = 180;
@@ -1811,7 +1892,7 @@ class Skin {
if ( ( ! $height === false )
&& ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
- print "rescaling by factor ". $height / $img->getHeight() . "<br>\n";
+ print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
$width = $img->getWidth() * $height / $img->getHeight();
}
$url = $img->createThumb( $width );
@@ -1824,28 +1905,28 @@ class Skin {
$alt = htmlspecialchars( $alt );
$u = $nt->escapeLocalURL();
- if ( $url == "" )
+ if ( $url == '' )
{
- $s = str_replace( "$1", $img->getName(), wfMsg("missingimage") );
+ $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
$s .= "<br>{$alt}<br>{$url}<br>\n";
} else {
- $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
- "<img src=\"{$url}\" alt=\"{$alt}\" /></a>";
+ $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
+ '<img src="'.$url.'" alt="'.$alt.'" /></a>';
}
- if ( "" != $align ) {
- $s = "<div class=\"float{$align}\"><span>{$s}</span>\n</div>";
+ if ( '' != $align ) {
+ $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
}
- return $prefix.$s.$postfix;
+ return str_replace("\n", ' ',$prefix.$s.$postfix);
}
- function makeThumbLinkObj( $img, $label = "", $align = "right", $boxwidth = 180, $boxheight=false, $framed=false ) {
+ function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false ) {
global $wgStylePath, $wgLang;
# $image = Title::makeTitle( Namespace::getImage(), $name );
$url = $img->getURL();
#$label = htmlspecialchars( $label );
- $alt = preg_replace( "/<[^>]*>/", "", $label);
+ $alt = preg_replace( '/<[^>]*>/', '', $label);
$alt = htmlspecialchars( $alt );
if ( $img->exists() )
@@ -1876,13 +1957,13 @@ class Skin {
$u = $img->getEscapeLocalURL();
- $more = htmlspecialchars( wfMsg( "thumbnail-more" ) );
- $magnifyalign = $wgLang->isRTL() ? "left" : "right";
- $textalign = $wgLang->isRTL() ? ' style="text-align:right"' : "";
+ $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
+ $magnifyalign = $wgLang->isRTL() ? 'left' : 'right';
+ $textalign = $wgLang->isRTL() ? ' style="text-align:right"' : '';
$s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
- if ( $thumbUrl == "" ) {
- $s .= str_replace( "$1", $img->getName(), wfMsg("missingimage") );
+ if ( $thumbUrl == '' ) {
+ $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
$zoomicon = '';
} else {
$s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
@@ -1897,8 +1978,8 @@ class Skin {
'width="15" height="11" alt="'.$more.'" /></a></div>';
}
}
- $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div>\n</div>";
- return $s;
+ $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
+ return str_replace("\n", ' ', $s);
}
function makeMediaLink( $name, $url, $alt = "" ) {
@@ -1908,14 +1989,20 @@ class Skin {
function makeMediaLinkObj( $nt, $alt = "" )
{
- $name = $nt->getDBKey();
- $url = Image::wfImageUrl( $name );
- if ( empty( $alt ) ) {
- $alt = preg_replace( '/\.(.+?)^/', '', $name );
+ if ( ! isset( $nt ) )
+ {
+ ### HOTFIX. Instead of breaking, return empry string.
+ $s = $alt;
+ } else {
+ $name = $nt->getDBKey();
+ $url = Image::wfImageUrl( $name );
+ if ( empty( $alt ) ) {
+ $alt = preg_replace( '/\.(.+?)^/', '', $name );
+ }
+
+ $u = htmlspecialchars( $url );
+ $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
}
-
- $u = htmlspecialchars( $url );
- $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
return $s;
}
@@ -1923,7 +2010,7 @@ class Skin {
{
global $wgLang;
- if ( "" == $key ) { $key = strtolower( $name ); }
+ if ( '' == $key ) { $key = strtolower( $name ); }
$pn = $wgLang->ucfirst( $name );
return $this->makeKnownLink( $wgLang->specialPage( $pn ),
wfMsg( $key ) );
@@ -1935,7 +2022,7 @@ class Skin {
if( $escape ) {
$text = htmlspecialchars( $text );
}
- return "<a href=\"$url\"$style>$text</a>";
+ return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
}
# Called by history lists and recent changes
@@ -1947,15 +2034,15 @@ class Skin {
$this->rc_cache = array() ;
$this->rcMoveIndex = 0;
$this->rcCacheIndex = 0 ;
- $this->lastdate = "";
+ $this->lastdate = '';
$this->rclistOpen = false;
- return "";
+ return '';
}
function beginImageHistoryList()
{
- $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
- "<p>" . wfMsg( "imghistlegend" ) . "</p>\n<ul class='special'>";
+ $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
+ "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
return $s;
}
@@ -1977,57 +2064,58 @@ class Skin {
# Get rc_xxxx variables
extract( $rcObj->mAttribs ) ;
- $curIdEq = "curid=$rc_cur_id";
+ $curIdEq = 'curid='.$rc_cur_id;
# Spacer image
- $r = "" ;
+ $r = '' ;
- $r .= "<img src='{$wgStylePath}/images/Arr_.png' width='12' height='12' border='0' />" ; $r .= "<tt>" ;
+ $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
+ $r .= '<tt>' ;
- if ( $rc_type == RC_MOVE ) {
- $r .= "&nbsp;&nbsp;";
+ if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
+ $r .= '&nbsp;&nbsp;';
} else {
# M & N (minor & new)
- $M = wfMsg( "minoreditletter" );
- $N = wfMsg( "newpageletter" );
+ $M = wfMsg( 'minoreditletter' );
+ $N = wfMsg( 'newpageletter' );
if ( $rc_type == RC_NEW ) {
$r .= $N ;
} else {
- $r .= "&nbsp;" ;
+ $r .= '&nbsp;' ;
}
if ( $rc_minor ) {
$r .= $M ;
} else {
- $r .= "&nbsp;" ;
+ $r .= '&nbsp;' ;
}
}
# Timestamp
- $r .= " ".$rcObj->timestamp." " ;
- $r .= "</tt>" ;
+ $r .= ' '.$rcObj->timestamp.' ' ;
+ $r .= '</tt>' ;
# Article link
$link = $rcObj->link ;
- if ( $rcObj->watched ) $link = "<strong>{$link}</strong>" ;
+ if ( $rcObj->watched ) $link = '<strong>'.$link.'</strong>' ;
$r .= $link ;
- # Cur
- $r .= " (" ;
- $r .= $rcObj->curlink ;
- $r .= "; " ;
+ # Diff
+ $r .= ' (' ;
+ $r .= $rcObj->difflink ;
+ $r .= '; ' ;
# Hist
- $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
+ $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
# User/talk
- $r .= ") . . ".$rcObj->userlink ;
+ $r .= ') . . '.$rcObj->userlink ;
$r .= $rcObj->usertalklink ;
# Comment
- if ( $rc_comment != "" && $rc_type != RC_MOVE ) {
+ if ( $rc_comment != '' && $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
$rc_comment=$this->formatComment($rc_comment);
- $r .= $wgLang->emphasize( " (".$rc_comment.")" );
+ $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
}
$r .= "<br />\n" ;
@@ -2039,9 +2127,9 @@ class Skin {
{
global $wgStylePath, $wgLang ;
- $r = "" ;
- $M = wfMsg( "minoreditletter" );
- $N = wfMsg( "newpageletter" );
+ $r = '' ;
+ $M = wfMsg( 'minoreditletter' );
+ $N = wfMsg( 'newpageletter' );
# Collate list of users
$isnew = false ;
@@ -2063,86 +2151,86 @@ class Skin {
if ( $count > 1 ) $text .= " ({$count}&times;)" ;
array_push ( $users , $text ) ;
}
- $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
+ $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
# Arrow
- $rci = "RCI{$this->rcCacheIndex}" ;
- $rcl = "RCL{$this->rcCacheIndex}" ;
- $rcm = "RCM{$this->rcCacheIndex}" ;
- $toggleLink = "javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")" ;
- $arrowdir = $wgLang->isRTL() ? "l" : "r";
- $tl = "<span id='{$rcm}'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_{$arrowdir}.png' width='12' height='12' /></a></span>" ;
- $tl .= "<span id='{$rcl}' style='display:none'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_d.png' width='12' height='12' /></a></span>" ;
+ $rci = 'RCI'.$this->rcCacheIndex ;
+ $rcl = 'RCL'.$this->rcCacheIndex ;
+ $rcm = 'RCM'.$this->rcCacheIndex ;
+ $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
+ $arrowdir = $wgLang->isRTL() ? 'l' : 'r';
+ $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
+ $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
$r .= $tl ;
# Main line
# M/N
- $r .= "<tt>" ;
+ $r .= '<tt>' ;
if ( $isnew ) $r .= $N ;
- else $r .= "&nbsp;" ;
- $r .= "&nbsp;" ; # Minor
+ else $r .= '&nbsp;' ;
+ $r .= '&nbsp;' ; # Minor
# Timestamp
- $r .= " ".$block[0]->timestamp." " ;
- $r .= "</tt>" ;
+ $r .= ' '.$block[0]->timestamp.' ' ;
+ $r .= '</tt>' ;
# Article link
$link = $block[0]->link ;
- if ( $block[0]->watched ) $link = "<strong>{$link}</strong>" ;
+ if ( $block[0]->watched ) $link = '<strong>'.$link.'</strong>' ;
$r .= $link ;
- $curIdEq = "curid=" . $block[0]->mAttribs['rc_cur_id'];
+ $curIdEq = 'curid=' . $block[0]->mAttribs['rc_cur_id'];
if ( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
# Changes
- $r .= " (".count($block)." " ;
- if ( $isnew ) $r .= wfMsg("changes");
- else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
- "{$curIdEq}&diff=0&oldid=".$oldid ) ;
- $r .= "; " ;
+ $r .= ' ('.count($block).' ' ;
+ if ( $isnew ) $r .= wfMsg('changes');
+ else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
+ $curIdEq.'&diff=0&oldid='.$oldid ) ;
+ $r .= '; ' ;
# History
- $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
- $r .= ")" ;
+ $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
+ $r .= ')' ;
}
$r .= $users ;
$r .= "<br />\n" ;
# Sub-entries
- $r .= "<div id='{$rci}' style='display:none'>" ;
+ $r .= '<div id="'.$rci.'" style="display:none">' ;
foreach ( $block AS $rcObj ) {
# Get rc_xxxx variables
extract( $rcObj->mAttribs );
- $r .= "<img src='{$wgStylePath}/images/Arr_.png' width=12 height=12 />";
- $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
+ $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
+ $r .= '<tt>&nbsp; &nbsp; &nbsp; &nbsp;' ;
if ( $rc_new ) $r .= $N ;
- else $r .= "&nbsp;" ;
+ else $r .= '&nbsp;' ;
if ( $rc_minor ) $r .= $M ;
- else $r .= "&nbsp;" ;
- $r .= "</tt>" ;
+ else $r .= '&nbsp;' ;
+ $r .= '</tt>' ;
- $o = "" ;
+ $o = '' ;
if ( $rc_last_oldid != 0 ) {
- $o = "oldid=".$rc_last_oldid ;
+ $o = 'oldid='.$rc_last_oldid ;
}
if ( $rc_type == RC_LOG ) {
$link = $rcObj->timestamp ;
} else {
$link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp , "{$curIdEq}&$o" ) ;
}
- $link = "<tt>{$link}</tt>" ;
+ $link = '<tt>'.$link.'</tt>' ;
$r .= $link ;
- $r .= " (" ;
+ $r .= ' (' ;
$r .= $rcObj->curlink ;
- $r .= "; " ;
+ $r .= '; ' ;
$r .= $rcObj->lastlink ;
- $r .= ") . . ".$rcObj->userlink ;
+ $r .= ') . . '.$rcObj->userlink ;
$r .= $rcObj->usertalklink ;
- if ( $rc_comment != "" ) {
+ if ( $rc_comment != '' ) {
$rc_comment=$this->formatComment($rc_comment);
- $r .= $wgLang->emphasize( " (".$rc_comment.")" ) ;
+ $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
}
$r .= "<br />\n" ;
}
@@ -2157,8 +2245,8 @@ class Skin {
function recentChangesBlock ()
{
global $wgStylePath ;
- if ( count ( $this->rc_cache ) == 0 ) return "" ;
- $blockOut = "";
+ if ( count ( $this->rc_cache ) == 0 ) return '' ;
+ $blockOut = '';
foreach ( $this->rc_cache AS $secureName => $block ) {
if ( count ( $block ) < 2 ) {
$blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
@@ -2167,7 +2255,7 @@ class Skin {
}
}
- return "<div>{$blockOut}</div>" ;
+ return '<div>'.$blockOut.'</div>' ;
}
# Called in a loop over all displayed RC entries
@@ -2175,7 +2263,7 @@ class Skin {
function recentChangesLine( &$rc, $watched = false )
{
global $wgUser ;
- $usenew = $wgUser->getOption( "usenewrc" );
+ $usenew = $wgUser->getOption( 'usenewrc' );
if ( $usenew )
$line = $this->recentChangesLineNew ( $rc, $watched ) ;
else
@@ -2189,70 +2277,73 @@ class Skin {
# Extract DB fields into local scope
extract( $rc->mAttribs );
- $curIdEq = "curid=" . $rc_cur_id;
+ $curIdEq = 'curid=' . $rc_cur_id;
# Make date header if necessary
$date = $wgLang->date( $rc_timestamp, true);
- $s = "";
+ $s = '';
if ( $date != $this->lastdate ) {
- if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
+ if ( '' != $this->lastdate ) { $s .= "</ul>\n"; }
$s .= "<h4>{$date}</h4>\n<ul class='special'>";
$this->lastdate = $date;
$this->rclistOpen = true;
}
- $s .= "<li> ";
+ $s .= '<li> ';
- if ( $rc_type == RC_MOVE ) {
+ if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
# Diff
- $s .= "(" . wfMsg( "diff" ) . ") (";
+ $s .= '(' . wfMsg( 'diff' ) . ') (';
# Hist
- $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
- ") . . ";
+ $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
+ ') . . ';
# "[[x]] moved to [[y]]"
-
- $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
- $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
-
+ if ( $rc_type == RC_MOVE ) {
+ $msg = '1movedto2';
+ } else {
+ $msg = '1movedto2_redir';
+ }
+ $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
+ $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
} else {
# Diff link
if ( $rc_type == RC_NEW || $rc_type == RC_LOG ) {
- $diffLink = wfMsg( "diff" );
+ $diffLink = wfMsg( 'diff' );
} else {
- $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
- "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" ,'' ,'' , ' tabindex="'.$rc->counter.'"');
+ $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
+ $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter.'"');
}
- $s .= "($diffLink) (";
+ $s .= '('.$diffLink.') (';
# History link
- $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
- $s .= ") . . ";
+ $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
+ $s .= ') . . ';
# M and N (minor and new)
- $M = wfMsg( "minoreditletter" );
- $N = wfMsg( "newpageletter" );
- if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
- if ( $rc_type == RC_NEW ) { $s .= "<strong>{$N}</strong>"; }
+ $M = wfMsg( 'minoreditletter' );
+ $N = wfMsg( 'newpageletter' );
+ if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
+ if ( $rc_type == RC_NEW ) { $s .= '<strong>'.$N.'</strong>'; }
# Article link
- $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
+ $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
if ( $watched ) {
- $articleLink = "<strong>{$articleLink}</strong>";
+ $articleLink = '<strong>'.$articleLink.'</strong>';
}
- $s .= " $articleLink";
+ $s .= ' '.$articleLink;
}
# Timestamp
- $s .= "; " . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . " . . ";
+ $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
# User link (or contributions for unregistered users)
if ( 0 == $rc_user ) {
- $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
- $rc_user_text, "target=" . $rc_user_text );
+ $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
+ $rc_user_text, 'target=' . $rc_user_text );
} else {
- $userLink = $this->makeLink( $wgLang->getNsText( NS_USER ) . ":{$rc_user_text}", $rc_user_text );
+ $userLink = $this->makeLink( $wgLang->getNsText( NS_USER ) . ':'.$rc_user_text, $rc_user_text );
}
$s .= $userLink;
@@ -2260,28 +2351,28 @@ class Skin {
$talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
global $wgDisableAnonTalk;
if( 0 == $rc_user && $wgDisableAnonTalk ) {
- $userTalkLink = "";
+ $userTalkLink = '';
} else {
$utns=$wgLang->getNsText(NS_USER_TALK);
- $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
+ $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
}
# Block link
- $blockLink="";
+ $blockLink='';
if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
$blockLink = $this->makeKnownLink( $wgLang->specialPage(
- "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
+ 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
}
if($blockLink) {
- if($userTalkLink) $userTalkLink .= " | ";
+ if($userTalkLink) $userTalkLink .= ' | ';
$userTalkLink .= $blockLink;
}
- if($userTalkLink) $s.=" ({$userTalkLink})";
+ if($userTalkLink) $s.=' ('.$userTalkLink.')';
# Add comment
- if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE ) {
+ if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
$rc_comment=$this->formatComment($rc_comment);
- $s .= $wgLang->emphasize(" (" . $rc_comment . ")");
+ $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
}
$s .= "</li>\n";
@@ -2298,11 +2389,11 @@ class Skin {
# Extract fields from DB into the function scope (rc_xxxx variables)
extract( $rc->mAttribs );
- $curIdEq = "curid=" . $rc_cur_id;
+ $curIdEq = 'curid=' . $rc_cur_id;
# If it's a new day, add the headline and flush the cache
$date = $wgLang->date( $rc_timestamp, true);
- $ret = "" ;
+ $ret = '' ;
if ( $date != $this->lastdate ) {
# Process current cache
$ret = $this->recentChangesBlock () ;
@@ -2312,12 +2403,16 @@ class Skin {
}
# Make article link
- if ( $rc_type == RC_MOVE ) {
- $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
- $clink .= " " . wfMsg("movedto") . " ";
- $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
+ if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
+ if ( $rc_type == RC_MOVE ) {
+ $msg = "1movedto2";
+ } else {
+ $msg = "1movedto2_redir";
+ }
+ $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
+ $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
} else {
- $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
+ $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
}
$time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
@@ -2325,63 +2420,68 @@ class Skin {
$rc->link = $clink ;
$rc->timestamp = $time;
- # Make "cur" link
- if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE) {
- $curLink = wfMsg( "cur" );
- } else {
- $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
- "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" ,'' ,'' , ' tabindex="'.$baseRC->counter.'"' );
+ # Make "cur" and "diff" links
+ if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
+ $curLink = wfMsg( 'cur' );
+ $diffLink = wfMsg( 'diff' );
+ } else {
+ $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
+ $aprops = ' tabindex="'.$baseRC->counter.'"';
+ $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
+ $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
}
# Make "last" link
$titleObj = $rc->getTitle();
- if ( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE ) {
- $lastLink = wfMsg( "last" );
+ if ( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
+ $lastLink = wfMsg( 'last' );
} else {
- $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
- "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
+ $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
+ $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
}
# Make user link (or user contributions for unregistered users)
if ( 0 == $rc_user ) {
- $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
- $rc_user_text, "target=" . $rc_user_text );
+ $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
+ $rc_user_text, 'target=' . $rc_user_text );
} else {
$userLink = $this->makeLink( $wgLang->getNsText(
- Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
+ Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
}
$rc->userlink = $userLink ;
$rc->lastlink = $lastLink ;
$rc->curlink = $curLink ;
+ $rc->difflink = $diffLink;
+
# Make user talk link
$utns=$wgLang->getNsText(NS_USER_TALK);
$talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
- $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
+ $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
global $wgDisableAnonTalk;
if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
$blockLink = $this->makeKnownLink( $wgLang->specialPage(
- "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
+ 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
if( $wgDisableAnonTalk )
- $rc->usertalklink = " ({$blockLink})";
+ $rc->usertalklink = ' ('.$blockLink.')';
else
- $rc->usertalklink = " ({$userTalkLink} | {$blockLink})";
+ $rc->usertalklink = ' ('.$userTalkLink.' | '.$blockLink.')';
} else {
if( $wgDisableAnonTalk && ($rc_user == 0) )
- $rc->usertalklink = "";
+ $rc->usertalklink = '';
else
- $rc->usertalklink = " ({$userTalkLink})";
+ $rc->usertalklink = ' ('.$userTalkLink.')';
}
# Put accumulated information into the cache, for later display
# Page moves go on their own line
$title = $rc->getTitle();
$secureName = $title->getPrefixedDBkey();
- if ( $rc_type == RC_MOVE ) {
+ if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
# Use an @ character to prevent collision with page names
- $this->rc_cache["@@" . ($this->rcMoveIndex++)] = array($rc);
+ $this->rc_cache['@@' . ($this->rcMoveIndex++)] = array($rc);
} else {
if ( !isset ( $this->rc_cache[$secureName] ) ) $this->rc_cache[$secureName] = array() ;
array_push ( $this->rc_cache[$secureName] , $rc ) ;
@@ -2410,33 +2510,34 @@ class Skin {
# some nasty regex.
# We look for all comments, match any text before and after the comment,
# add a separator where needed and format the comment itself with CSS
- while (preg_match("/(.*)\/\*\s*(.*?)\s*\*\/(.*)/", $comment,$match)) {
+ while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
$pre=$match[1];
$auto=$match[2];
$post=$match[3];
- $sep="-";
- if($pre) { $auto="$sep ".$auto; }
- if($post) { $auto.=" $sep"; }
- $auto="<span class=\"autocomment\">".$auto."</span>";
+ $sep='-';
+ if($pre) { $auto = $sep.' '.$auto; }
+ if($post) { $auto .= ' '.$sep; }
+ $auto='<span class="autocomment">'.$auto.'</span>';
$comment=$pre.$auto.$post;
}
# format regular and media links - all other wiki formatting
# is ignored
- while(preg_match("/\[\[(.*?)(\|(.*?))*\]\]/",$comment,$match)) {
+ while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
- $medians = $wgLang->getNsText(Namespace::getMedia());
- $func="makeLink";
- if(preg_match("/^".$medians."/i",$match[1])) {
- $func="makeMediaLink";
+ $medians = $wgLang->getNsText(Namespace::getMedia()).':';
+ $func='makeLink';
+ if(preg_match('/^'.$medians.'/i',$match[1])) {
+ $func='makeMediaLink';
}
+ # Handle link renaming [[foo|text]] will show link as "text"
if(isset($match[3]) ) {
$comment=
- preg_replace("/\[\[(.*?)\]\]/",
+ preg_replace('/\[\[(.*?)\]\]/',
$this->$func($match[1],$match[3]),$comment,1);
} else {
$comment=
- preg_replace("/\[\[(.*?)\]\]/",
+ preg_replace('/\[\[(.*?)\]\]/',
$this->$func($match[1],$match[1]),$comment,1);
}
}
@@ -2450,18 +2551,18 @@ class Skin {
global $wgUser, $wgLang, $wgTitle;
$datetime = $wgLang->timeanddate( $timestamp, true );
- $del = wfMsg( "deleteimg" );
- $cur = wfMsg( "cur" );
+ $del = wfMsg( 'deleteimg' );
+ $cur = wfMsg( 'cur' );
if ( $iscur ) {
$url = Image::wfImageUrl( $img );
$rlink = $cur;
if ( $wgUser->isSysop() ) {
- $link = $wgTitle->escapeLocalURL( "image=" . $wgTitle->getPartialURL() .
- "&action=delete" );
+ $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
+ '&action=delete' );
$style = $this->getInternalLinkAttributes( $link, $del );
- $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
+ $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
} else {
$dlink = $del;
}
@@ -2469,15 +2570,15 @@ class Skin {
$url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
if( $wgUser->getID() != 0 ) {
$rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
- wfMsg( "revertimg" ), "action=revert&oldimage=" .
+ wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
urlencode( $img ) );
$dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
- $del, "action=delete&oldimage=" . urlencode( $img ) );
+ $del, 'action=delete&oldimage=' . urlencode( $img ) );
} else {
# Having live active links for non-logged in users
# means that bots and spiders crawling our site can
# inadvertently change content. Baaaad idea.
- $rlink = wfMsg( "revertimg" );
+ $rlink = wfMsg( 'revertimg' );
$dlink = $del;
}
}
@@ -2485,24 +2586,24 @@ class Skin {
$userlink = $usertext;
} else {
$userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
- ":{$usertext}", $usertext );
+ ':'.$usertext, $usertext );
}
- $nbytes = wfMsg( "nbytes", $size );
+ $nbytes = wfMsg( 'nbytes', $size );
$style = $this->getInternalLinkAttributes( $url, $datetime );
$s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
. " . . {$userlink} ({$nbytes})";
- if ( "" != $description && "*" != $description ) {
+ if ( '' != $description && '*' != $description ) {
$sk=$wgUser->getSkin();
- $s .= $wgLang->emphasize(" (" . $sk->formatComment($description) . ")");
+ $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
}
$s .= "</li>\n";
return $s;
}
function tocIndent($level) {
- return str_repeat( "<div class='tocindent'>\n", $level>0 ? $level : 0 );
+ return str_repeat( '<div class="tocindent">'."\n", $level>0 ? $level : 0 );
}
function tocUnindent($level) {
@@ -2511,11 +2612,11 @@ class Skin {
# parameter level defines if we are on an indentation level
function tocLine( $anchor, $tocline, $level ) {
- $link = "<a href=\"#$anchor\">$tocline</a><br />";
+ $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
if($level) {
- return "$link\n";
+ return $link."\n";
} else {
- return "<div class='tocline'>$link</div>\n";
+ return '<div class="tocline">'.$link."</div>\n";
}
}
@@ -2523,45 +2624,45 @@ class Skin {
function tocTable($toc) {
# note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
# try min-width & co when somebody gets a chance
- $hideline = " <script type='text/javascript'>showTocToggle(\"" . addslashes( wfMsg("showtoc") ) . "\",\"" . addslashes( wfMsg("hidetoc") ) . "\")</script>";
+ $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
return
- "<table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
- "<b>".wfMsg("toc")."</b>" .
+ '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
+ '<b>'.wfMsg('toc').'</b>' .
$hideline .
- "</td></tr><tr id='tocinside'><td>\n".
+ '</td></tr><tr id="tocinside"><td>'."\n".
$toc."</td></tr></table>\n";
}
# These two do not check for permissions: check $wgTitle->userCanEdit before calling them
function editSectionScript( $section, $head ) {
global $wgTitle, $wgRequest;
- if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
+ if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
return $head;
}
- $url = $wgTitle->escapeLocalURL( "action=edit&section=$section" );
- return "<span oncontextmenu='document.location=\"$url\";return false;'>{$head}</span>";
+ $url = $wgTitle->escapeLocalURL( 'action=edit&section='.$section );
+ return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
}
function editSectionLink( $section ) {
global $wgRequest;
global $wgTitle, $wgUser, $wgLang;
- if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
+ if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
# Section edit links would be out of sync on an old page.
# But, if we're diffing to the current page, they'll be
# correct.
- return "";
+ return '';
}
- $editurl = "&section={$section}";
- $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
+ $editurl = '&section='.$section;
+ $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
if( $wgLang->isRTL() ) {
- $farside = "left";
- $nearside = "right";
+ $farside = 'left';
+ $nearside = 'right';
} else {
- $farside = "right";
- $nearside = "left";
+ $farside = 'right';
+ $nearside = 'left';
}
return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
@@ -2583,12 +2684,12 @@ class Skin {
// can figure out a way to make them work in IE. However, we should make
// sure these keys are not defined on the edit page.
$toolarray=array(
- array( "image"=>"button_bold.png",
- "open"=>"\'\'\'",
- "close"=>"\'\'\'",
- "sample"=>wfMsg("bold_sample"),
- "tip"=>wfMsg("bold_tip"),
- "key"=>"B"
+ array( 'image'=>'button_bold.png',
+ 'open'=>"\'\'\'",
+ 'close'=>"\'\'\'",
+ 'sample'=>wfMsg('bold_sample'),
+ 'tip'=>wfMsg('bold_tip'),
+ 'key'=>'B'
),
array( "image"=>"button_italic.png",
"open"=>"\'\'",
@@ -2666,16 +2767,16 @@ class Skin {
$toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
foreach($toolarray as $tool) {
- $image=$wgStylePath."/images/".$tool["image"];
- $open=$tool["open"];
- $close=$tool["close"];
- $sample = addslashes( $tool["sample"] );
+ $image=$wgStylePath.'/images/'.$tool['image'];
+ $open=$tool['open'];
+ $close=$tool['close'];
+ $sample = addslashes( $tool['sample'] );
// Note that we use the tip both for the ALT tag and the TITLE tag of the image.
// Older browsers show a "speedtip" type message only for ALT.
// Ideally these should be different, realistically they
// probably don't need to be.
- $tip = addslashes( $tool["tip"] );
+ $tip = addslashes( $tool['tip'] );
#$key = $tool["key"];
@@ -2690,14 +2791,4 @@ class Skin {
}
}
-
-require_once( "SkinStandard.php" );
-require_once( "SkinNostalgia.php" );
-require_once( "SkinCologneBlue.php" );
-
-if( $wgUsePHPTal ) {
- require_once( "SkinPHPTal.php" );
-}
-
-
?>
diff --git a/includes/SkinCologneBlue.php b/includes/SkinCologneBlue.php
index 09336459db17..212e3939fddd 100644
--- a/includes/SkinCologneBlue.php
+++ b/includes/SkinCologneBlue.php
@@ -7,6 +7,9 @@ class SkinCologneBlue extends Skin {
{
return "cologneblue.css";
}
+ function getSkinName() {
+ return "cologneblue";
+ }
function doBeforeContent()
{
@@ -32,7 +35,9 @@ class SkinCologneBlue extends Skin {
$s .= "</td><td align='right'>" ;
$s .= "<font size='-1'><span id='langlinks'>" ;
- $s .= str_replace ( "<br>" , "" , $this->otherLanguages() ) ;
+ $s .= str_replace ( "<br>" , "" , $this->otherLanguages() );
+ $cat = $this->getCategoryLinks();
+ if( $cat ) $s .= "<br />$cat\n";
$s .= "<br />" . $this->pageTitleLinks();
$s .= "</span></font>";
@@ -79,8 +84,7 @@ class SkinCologneBlue extends Skin {
function doGetUserStyles()
{
global $wgUser, $wgOut, $wgStyleSheetPath;
-
- $s = parent::doGetUserStyles();
+ $s = '';
$qb = $this->qbSetting();
if ( 2 == $qb ) { # Right
@@ -95,6 +99,7 @@ class SkinCologneBlue extends Skin {
"#article { margin-left:148px; margin-right: 4px; } \n" .
"body>#quickbar { position:fixed; left:4px; top:4px; overflow:auto ;bottom:4px;} \n"; # Hides from IE
}
+ $s .= parent::doGetUserStyles();
return $s;
}
function sysLinks()
diff --git a/includes/SkinNostalgia.php b/includes/SkinNostalgia.php
index 3d990ee6705e..c97c681ddd9b 100644
--- a/includes/SkinNostalgia.php
+++ b/includes/SkinNostalgia.php
@@ -12,6 +12,9 @@ class SkinNostalgia extends Skin {
{
return "nostalgia.css";
}
+ function getSkinName() {
+ return "nostalgia";
+ }
function doBeforeContent()
{
@@ -28,6 +31,9 @@ class SkinNostalgia extends Skin {
$ol = $this->otherLanguages();
if($ol) $s .= "<br />" . $ol;
+
+ $cat = $this->getCategoryLinks();
+ if($cat) $s .= "<br />" . $cat;
$s .= "<br clear='all' /><hr />\n</div>\n";
$s .= "\n<div id='article'>";
diff --git a/includes/SkinPHPTal.php b/includes/SkinPHPTal.php
index bf39da259933..f56360f60f3a 100644
--- a/includes/SkinPHPTal.php
+++ b/includes/SkinPHPTal.php
@@ -27,6 +27,7 @@
# http://www.gnu.org/copyleft/gpl.html
require_once "GlobalFunctions.php";
+ global $IP;
require_once $IP."/PHPTAL-NP-0.7.0/libs/PHPTAL.php";
class MediaWiki_I18N extends PHPTAL_I18N
@@ -62,7 +63,7 @@
global $wgTitle, $wgArticle, $wgUser, $wgLang, $wgOut;
global $wgScript, $wgStylePath, $wgLanguageCode, $wgUseNewInterlanguage;
global $wgMimeType, $wgOutputEncoding, $wgUseDatabaseMessages, $wgRequest;
- global $wgDisableCounters, $wgLogo, $action, $wgFeedClasses;
+ global $wgDisableCounters, $wgLogo, $action, $wgFeedClasses, $wgSiteNotice;
extract( $wgRequest->getValues( 'oldid', 'diff' ) );
@@ -83,20 +84,27 @@
$this->userpageUrlDetails = $this->makeUrlDetails($this->userpage);
$this->usercss = $this->userjs = $this->userjsprev = false;
- if( $this->loggedin ) { $this->setupUserCssJs(); }
+ $this->setupUserCssJs();
$this->titletxt = $wgTitle->getPrefixedText();
$tpl->set( "title", $wgOut->getPageTitle() );
$tpl->set( "pagetitle", $wgOut->getHTMLTitle() );
- $tpl->setRef( "thispage", &$this->thispage );
+ $tpl->setRef( "thispage", $this->thispage );
$subpagestr = $this->subPageSubtitle();
$tpl->set(
"subtitle", !empty($subpagestr)?
'<span class="subpages">'.$subpagestr.'</span>'.$out->getSubtitle():
$out->getSubtitle()
);
+ $undelete = $this->getUndeleteLink();
+ $tpl->set(
+ "undelete", !empty($undelete)?
+ '<span class="subpages">'.$undelete.'</span>':
+ ''
+ );
+
$tpl->set( 'catlinks', $this->getCategories());
if( $wgOut->isSyndicated() ) {
$feeds = array();
@@ -107,13 +115,14 @@
'ttip' => wfMsg('tooltip-'.$format)
);
}
- $tpl->setRef( 'feeds', &$feeds );
+ $tpl->setRef( 'feeds', $feeds );
}
- $tpl->setRef( 'mimetype', &$wgMimeType );
- $tpl->setRef( 'charset', &$wgOutputEncoding );
+ $tpl->setRef( 'mimetype', $wgMimeType );
+ $tpl->setRef( 'charset', $wgOutputEncoding );
$tpl->set( 'headlinks', $out->getHeadLinks() );
- $tpl->setRef( 'skinname', &$this->skinname );
- $tpl->setRef( "loggedin", &$this->loggedin );
+ $tpl->setRef( 'skinname', $this->skinname );
+ $tpl->setRef( "loggedin", $this->loggedin );
+ $tpl->set('nsclass', 'ns-'.$wgTitle->getNamespace());
/* XXX currently unused, might get useful later
$tpl->set( "editable", ($wgTitle->getNamespace() != NS_SPECIAL ) );
$tpl->set( "exists", $wgTitle->getArticleID() != 0 );
@@ -123,18 +132,23 @@
$tpl->set( "sysop", $wgUser->isSysop() );
*/
$tpl->set( "searchaction", $this->escapeSearchLink() );
- $tpl->setRef( "stylepath", &$wgStylePath );
- $tpl->setRef( "logopath", &$wgLogo );
- $tpl->setRef( "lang", &$wgLanguageCode );
+ $tpl->setRef( "stylepath", $wgStylePath );
+ $tpl->setRef( "logopath", $wgLogo );
+ $tpl->setRef( "lang", $wgLanguageCode );
$tpl->set( "dir", $wgLang->isRTL() ? "rtl" : "ltr" );
$tpl->set( "rtl", $wgLang->isRTL() );
$tpl->set( "langname", $wgLang->getLanguageName( $wgLanguageCode ) );
- $tpl->setRef( "username", &$this->username );
- $tpl->setRef( "userpage", &$this->userpage);
- $tpl->setRef( "userpageurl", &$this->userpageUrlDetails['href']);
- $tpl->setRef( "usercss", &$this->usercss);
- $tpl->setRef( "userjs", &$this->userjs);
- $tpl->setRef( "userjsprev", &$this->userjsprev);
+ $tpl->setRef( "username", $this->username );
+ $tpl->setRef( "userpage", $this->userpage);
+ $tpl->setRef( "userpageurl", $this->userpageUrlDetails['href']);
+ $tpl->setRef( "usercss", $this->usercss);
+ $tpl->setRef( "userjs", $this->userjs);
+ $tpl->setRef( "userjsprev", $this->userjsprev);
+ if($this->loggedin) {
+ $tpl->set( "jsvarurl", $this->makeUrl('-','action=raw&gen=js&smaxage=0') );
+ } else {
+ $tpl->set( "jsvarurl", $this->makeUrl('-','action=raw&gen=js') );
+ }
if( $wgUser->getNewtalk() ) {
$usertitle = Title::newFromText( $this->userpage );
$usertalktitle = $usertitle->getTalkPage();
@@ -151,8 +165,8 @@
$ntl = "";
}
- $tpl->setRef( "newtalk", &$ntl );
- $tpl->setRef( "skin", &$this);
+ $tpl->setRef( "newtalk", $ntl );
+ $tpl->setRef( "skin", $this);
$tpl->set( "logo", $this->logoText() );
if ( $wgOut->isArticle() and (!isset( $oldid ) or isset( $diff )) and 0 != $wgArticle->getID() ) {
if ( !$wgDisableCounters ) {
@@ -163,16 +177,20 @@
}
$tpl->set('lastmod', $this->lastModified());
$tpl->set('copyright',$this->getCopyright());
+ } elseif ( isset( $oldid ) && !isset( $diff ) ) {
+ $tpl->set('copyright', $this->getCopyright());
}
+
$tpl->set( "copyrightico", $this->getCopyrightIcon() );
$tpl->set( "poweredbyico", $this->getPoweredBy() );
$tpl->set( "disclaimer", $this->disclaimerLink() );
$tpl->set( "about", $this->aboutLink() );
- $tpl->setRef( "debug", &$out->mDebugtext );
+ $tpl->setRef( "debug", $out->mDebugtext );
$tpl->set( "reporttime", $out->reportTime() );
-
- $tpl->setRef( "bodytext", &$out->mBodytext );
+ $tpl->set( "sitenotice", $wgSiteNotice );
+
+ $tpl->setRef( "bodytext", $out->mBodytext );
$language_urls = array();
foreach( $wgOut->getLanguageLinks() as $l ) {
@@ -182,13 +200,13 @@
'class' => $wgLang->isRTL() ? 'rtl' : 'ltr');
}
if(count($language_urls)) {
- $tpl->setRef( 'language_urls', &$language_urls);
+ $tpl->setRef( 'language_urls', $language_urls);
} else {
$tpl->set('language_urls', false);
}
$tpl->set('personal_urls', $this->buildPersonalUrls());
$content_actions = $this->buildContentActionUrls();
- $tpl->setRef('content_actions', &$content_actions);
+ $tpl->setRef('content_actions', $content_actions);
// XXX: attach this from javascript, same with section editing
if($this->iseditable && $wgUser->getOption("editondblclick") )
{
@@ -218,72 +236,52 @@
$personal_urls['userpage'] = array(
'text' => $this->username,
'href' => &$this->userpageUrlDetails['href'],
- 'class' => $this->userpageUrlDetails['exists']?false:'new',
- 'ttip' => wfMsg('tooltip-userpage'),
- 'akey' => wfMsg('accesskey-userpage')
+ 'class' => $this->userpageUrlDetails['exists']?false:'new'
);
$usertalkUrlDetails = $this->makeTalkUrlDetails($this->userpage);
$personal_urls['mytalk'] = array(
'text' => wfMsg('mytalk'),
'href' => &$usertalkUrlDetails['href'],
- 'class' => $usertalkUrlDetails['exists']?false:'new',
- 'ttip' => wfMsg('tooltip-mytalk'),
- 'akey' => wfMsg('accesskey-mytalk')
+ 'class' => $usertalkUrlDetails['exists']?false:'new'
);
$personal_urls['preferences'] = array(
'text' => wfMsg('preferences'),
- 'href' => $this->makeSpecialUrl('Preferences'),
- 'ttip' => wfMsg('tooltip-preferences'),
- 'akey' => wfMsg('accesskey-preferences')
+ 'href' => $this->makeSpecialUrl('Preferences')
);
$personal_urls['watchlist'] = array(
'text' => wfMsg('watchlist'),
- 'href' => $this->makeSpecialUrl('Watchlist'),
- 'ttip' => wfMsg('tooltip-watchlist'),
- 'akey' => wfMsg('accesskey-watchlist')
+ 'href' => $this->makeSpecialUrl('Watchlist')
);
$personal_urls['mycontris'] = array(
'text' => wfMsg('mycontris'),
- 'href' => $this->makeSpecialUrl('Contributions','target=' . $this->username),
- 'ttip' => wfMsg('tooltip-mycontris'),
- 'akey' => wfMsg('accesskey-mycontris')
+ 'href' => $this->makeSpecialUrl('Contributions','target=' . urlencode( $this->username ) )
);
$personal_urls['logout'] = array(
'text' => wfMsg('userlogout'),
- 'href' => $this->makeSpecialUrl('Userlogout','returnto=' . $this->thisurl),
- 'ttip' => wfMsg('tooltip-logout'),
- 'akey' => wfMsg('accesskey-logout')
+ 'href' => $this->makeSpecialUrl('Userlogout','returnto=' . $this->thisurl )
);
} else {
if( $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] ) ) {
$personal_urls['anonuserpage'] = array(
'text' => $this->username,
'href' => &$this->userpageUrlDetails['href'],
- 'class' => $this->userpageUrlDetails['exists']?false:'new',
- 'ttip' => wfMsg('tooltip-anonuserpage'),
- 'akey' => wfMsg('accesskey-anonuserpage')
+ 'class' => $this->userpageUrlDetails['exists']?false:'new'
);
$usertalkUrlDetails = $this->makeTalkUrlDetails($this->userpage);
$personal_urls['anontalk'] = array(
'text' => wfMsg('anontalk'),
'href' => &$usertalkUrlDetails['href'],
- 'class' => $usertalkUrlDetails['exists']?false:'new',
- 'ttip' => wfMsg('tooltip-anontalk'),
- 'akey' => wfMsg('accesskey-anontalk')
+ 'class' => $usertalkUrlDetails['exists']?false:'new'
);
$personal_urls['anonlogin'] = array(
'text' => wfMsg('userlogin'),
- 'href' => $this->makeSpecialUrl('Userlogin', 'returnto='.$this->thisurl),
- 'ttip' => wfMsg('tooltip-login'),
- 'akey' => wfMsg('accesskey-login')
+ 'href' => $this->makeSpecialUrl('Userlogin', 'returnto=' . $this->thisurl )
);
} else {
$personal_urls['login'] = array(
'text' => wfMsg('userlogin'),
- 'href' => $this->makeSpecialUrl('Userlogin', 'returnto='.$this->thisurl),
- 'ttip' => wfMsg('tooltip-login'),
- 'akey' => wfMsg('accesskey-login')
+ 'href' => $this->makeSpecialUrl('Userlogin', 'returnto=' . $this->thisurl )
);
}
}
@@ -302,32 +300,27 @@
if( $this->iscontent ) {
- $content_actions['article'] = array('class' => (!Namespace::isTalk( $wgTitle->getNamespace())) ? 'selected' : false,
- 'text' => $this->getNameSpaceWord(),
- 'href' => $this->makeArticleUrl($this->thispage),
- 'ttip' => wfMsg('tooltip-article'),
- 'akey' => wfMsg('accesskey-article'));
+ $nskey = $this->getNameSpaceKey();
+ $content_actions[$nskey] = array('class' => (!Namespace::isTalk( $wgTitle->getNamespace())) ? 'selected' : false,
+ 'text' => wfMsg($nskey),
+ 'href' => $this->makeArticleUrl($this->thispage));
/* set up the classes for the talk link */
$talk_class = (Namespace::isTalk( $wgTitle->getNamespace()) ? 'selected' : false);
$talktitle = Title::newFromText( $this->titletxt );
$talktitle = $talktitle->getTalkPage();
- $this->checkTitle(&$talktitle, &$this->titletxt);
+ $this->checkTitle($talktitle, $this->titletxt);
if($talktitle->getArticleId() != 0) {
$content_actions['talk'] = array(
'class' => $talk_class,
'text' => wfMsg('talk'),
- 'href' => $this->makeTalkUrl($this->titletxt),
- 'ttip' => wfMsg('tooltip-talk'),
- 'akey' => wfMsg('accesskey-talk')
+ 'href' => $this->makeTalkUrl($this->titletxt)
);
} else {
$content_actions['talk'] = array(
'class' => $talk_class?$talk_class.' new':'new',
'text' => wfMsg('talk'),
- 'href' => $this->makeTalkUrl($this->titletxt,'action=edit'),
- 'ttip' => wfMsg('tooltip-talk'),
- 'akey' => wfMsg('accesskey-talk')
+ 'href' => $this->makeTalkUrl($this->titletxt,'action=edit')
);
}
@@ -338,35 +331,27 @@
$content_actions['edit'] = array(
'class' => ((($action == 'edit' or $action == 'submit') and $section != 'new') ? 'selected' : '').$istalkclass,
'text' => wfMsg('edit'),
- 'href' => $this->makeUrl($this->thispage, 'action=edit'.$oid),
- 'ttip' => wfMsg('tooltip-edit'),
- 'akey' => wfMsg('accesskey-edit')
+ 'href' => $this->makeUrl($this->thispage, 'action=edit'.$oid)
);
if ( $istalk ) {
$content_actions['addsection'] = array(
'class' => $section == 'new'?'selected':false,
'text' => wfMsg('addsection'),
- 'href' => $this->makeUrl($this->thispage, 'action=edit&section=new'),
- 'ttip' => wfMsg('tooltip-addsection'),
- 'akey' => wfMsg('accesskey-addsection')
+ 'href' => $this->makeUrl($this->thispage, 'action=edit&section=new')
);
}
} else {
$oid = ( $oldid && ! isset( $diff ) ) ? "&oldid={$oldid}" : '';
- $content_actions['edit'] = array('class' => ($action == 'edit') ? 'selected' : false,
+ $content_actions['viewsource'] = array('class' => ($action == 'edit') ? 'selected' : false,
'text' => wfMsg('viewsource'),
- 'href' => $this->makeUrl($this->thispage, 'action=edit'.$oid),
- 'ttip' => wfMsg('tooltip-viewsource'),
- 'akey' => wfMsg('accesskey-viewsource'));
+ 'href' => $this->makeUrl($this->thispage, 'action=edit'.$oid));
}
if ( $wgTitle->getArticleId() ) {
$content_actions['history'] = array('class' => ($action == 'history') ? 'selected' : false,
'text' => wfMsg('history_short'),
- 'href' => $this->makeUrl($this->thispage, 'action=history'),
- 'ttip' => wfMsg('tooltip-history'),
- 'akey' => wfMsg('accesskey-history'));
+ 'href' => $this->makeUrl($this->thispage, 'action=history'));
# XXX: is there a rollback action anywhere or is it planned?
# Don't recall where i got this from...
@@ -383,41 +368,32 @@
$content_actions['protect'] = array(
'class' => ($action == 'protect') ? 'selected' : false,
'text' => wfMsg('protect'),
- 'href' => $this->makeUrl($this->thispage, 'action=protect'),
- 'ttip' => wfMsg('tooltip-protect'),
- 'akey' => wfMsg('accesskey-protect')
+ 'href' => $this->makeUrl($this->thispage, 'action=protect')
);
} else {
$content_actions['unprotect'] = array(
'class' => ($action == 'unprotect') ? 'selected' : false,
'text' => wfMsg('unprotect'),
- 'href' => $this->makeUrl($this->thispage, 'action=unprotect'),
- 'ttip' => wfMsg('tooltip-protect'),
- 'akey' => wfMsg('accesskey-protect')
+ 'href' => $this->makeUrl($this->thispage, 'action=unprotect')
);
}
$content_actions['delete'] = array(
'class' => ($action == 'delete') ? 'selected' : false,
'text' => wfMsg('delete'),
- 'href' => $this->makeUrl($this->thispage, 'action=delete'),
- 'ttip' => wfMsg('tooltip-delete'),
- 'akey' => wfMsg('accesskey-delete')
+ 'href' => $this->makeUrl($this->thispage, 'action=delete')
);
}
if ( $wgUser->getID() != 0 ) {
if ( $wgTitle->userCanEdit()) {
$content_actions['move'] = array('class' => ($wgTitle->getDbKey() == 'Movepage' and $wgTitle->getNamespace == Namespace::getSpecial()) ? 'selected' : false,
'text' => wfMsg('move'),
- 'href' => $this->makeSpecialUrl('Movepage', 'target='.$this->thispage),
- 'ttip' => wfMsg('tooltip-move'),
- 'akey' => wfMsg('accesskey-move'));
+ 'href' => $this->makeSpecialUrl('Movepage', 'target='. urlencode( $this->thispage ))
+ );
} else {
$content_actions['move'] = array('class' => 'inactive',
'text' => wfMsg('move'),
- 'href' => false,
- 'ttip' => wfMsg('tooltip-nomove'),
- 'akey' => false);
+ 'href' => false);
}
}
@@ -428,9 +404,7 @@
$content_actions['delete'] = array(
'class' => false,
'text' => wfMsg( "undelete_short", $n ),
- 'href' => $this->makeSpecialUrl('Undelete/'.$this->thispage),
- 'ttip' => wfMsg('tooltip-undelete', $n),
- 'akey' => wfMsg('accesskey-undelete')
+ 'href' => $this->makeSpecialUrl('Undelete/'.$this->thispage)
);
}
}
@@ -440,16 +414,11 @@
if( !$wgTitle->userIsWatching()) {
$content_actions['watch'] = array('class' => ($action == 'watch' or $action == 'unwatch') ? 'selected' : false,
'text' => wfMsg('watch'),
- 'href' => $this->makeUrl($this->thispage, 'action=watch'),
- 'ttip' => wfMsg('tooltip-watch'),
- 'akey' => wfMsg('accesskey-watch'));
+ 'href' => $this->makeUrl($this->thispage, 'action=watch'));
} else {
$content_actions['watch'] = array('class' => ($action == 'unwatch' or $action == 'watch') ? 'selected' : false,
'text' => wfMsg('unwatch'),
- 'href' => $this->makeUrl($this->thispage, 'action=unwatch'),
- 'ttip' => wfMsg('tooltip-unwatch'),
- 'akey' => wfMsg('accesskey-unwatch'));
-
+ 'href' => $this->makeUrl($this->thispage, 'action=unwatch'));
}
}
} else {
@@ -457,9 +426,7 @@
$content_actions['article'] = array('class' => 'selected',
'text' => wfMsg('specialpage'),
- 'href' => false,
- 'ttip' => wfMsg('tooltip-specialpage'),
- 'akey' => false);
+ 'href' => false);
}
return $content_actions;
@@ -478,10 +445,10 @@
$nav_urls['mainpage'] = array('href' => htmlspecialchars( $this->makeI18nUrl('mainpage')));
$nav_urls['randompage'] = array('href' => htmlspecialchars( $this->makeSpecialUrl('Randompage')));
$nav_urls['recentchanges'] = array('href' => htmlspecialchars( $this->makeSpecialUrl('Recentchanges')));
- $nav_urls['whatlinkshere'] = array('href' => htmlspecialchars( $this->makeSpecialUrl('Whatlinkshere', 'target='.$this->thispage)));
+ $nav_urls['whatlinkshere'] = array('href' => htmlspecialchars( $this->makeSpecialUrl('Whatlinkshere', 'target='.urlencode( $this->thispage ))));
$nav_urls['currentevents'] = (wfMsg('currentevents') != '-') ? array('href' => htmlspecialchars( $this->makeI18nUrl('currentevents'))) : false;
$nav_urls['portal'] = (wfMsg('portal') != '-') ? array('href' => htmlspecialchars( $this->makeI18nUrl('portal-url'))) : false;
- $nav_urls['recentchangeslinked'] = array('href' => htmlspecialchars( $this->makeSpecialUrl('Recentchangeslinked', 'target='.$this->thispage)));
+ $nav_urls['recentchangeslinked'] = array('href' => htmlspecialchars( $this->makeSpecialUrl('Recentchangeslinked', 'target='.urlencode( $this->thispage ))));
$nav_urls['bugreports'] = array('href' => htmlspecialchars( $this->makeI18nUrl('bugreportspage')));
// $nav_urls['sitesupport'] = array('href' => htmlspecialchars( $this->makeI18nUrl('sitesupportpage')));
$nav_urls['sitesupport'] = array('href' => htmlspecialchars( $wgSiteSupportPage));
@@ -489,9 +456,13 @@
$nav_urls['upload'] = array('href' => htmlspecialchars( $this->makeSpecialUrl('Upload')));
$nav_urls['specialpages'] = array('href' => htmlspecialchars( $this->makeSpecialUrl('Specialpages')));
-
- $id=User::idFromName($wgTitle->getText());
- $ip=User::isIP($wgTitle->getText());
+ if( $wgTitle->getNamespace() == NS_USER || $wgTitle->getNamespace() == NS_USER_TALK ) {
+ $id = User::idFromName($wgTitle->getText());
+ $ip = User::isIP($wgTitle->getText());
+ } else {
+ $id = 0;
+ $ip = false;
+ }
if($id || $ip) { # both anons and non-anons have contri list
$nav_urls['contributions'] = array(
@@ -510,58 +481,101 @@
return $nav_urls;
}
- function getNameSpaceWord () {
+ function getNameSpaceKey () {
global $wgTitle;
switch ($wgTitle->getNamespace()) {
case NS_MAIN:
case NS_TALK:
- return wfMsg('nstab-main');
+ return 'nstab-main';
case NS_USER:
case NS_USER_TALK:
- return wfMsg('nstab-user');
+ return 'nstab-user';
case NS_MEDIA:
- return wfMsg('nstab-media');
+ return 'nstab-media';
case NS_SPECIAL:
- return wfMsg('nstab-special');
+ return 'nstab-special';
case NS_WP:
case NS_WP_TALK:
- return wfMsg('nstab-wp');
+ return 'nstab-wp';
case NS_IMAGE:
case NS_IMAGE_TALK:
- return wfMsg('nstab-image');
+ return 'nstab-image';
case NS_MEDIAWIKI:
case NS_MEDIAWIKI_TALK:
- return wfMsg('nstab-mediawiki');
+ return 'nstab-mediawiki';
case NS_TEMPLATE:
case NS_TEMPLATE_TALK:
- return wfMsg('nstab-template');
+ return 'nstab-template';
case NS_HELP:
case NS_HELP_TALK:
- return wfMsg('nstab-help');
+ return 'nstab-help';
case NS_CATEGORY:
case NS_CATEGORY_TALK:
- return wfMsg('nstab-category');
+ return 'nstab-category';
default:
- return wfMsg('nstab-main');
+ return 'nstab-main';
}
}
/* private */ function setupUserCssJs () {
global $wgRequest, $wgTitle;
$action = $wgRequest->getText('action');
- if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
- // css preview
- $this->usercss = $wgRequest->getText('wpTextbox1');
- } else {
- $this->usercss = '@import url('.
- $this->makeUrl($this->userpage.'/'.$this->skinname.'.css', 'action=raw&ctype=text/css').');';
+ # generated css
+ $this->usercss = '@import "'.$this->makeUrl('-','action=raw&gen=css').'";'."\n";
+
+ if( $this->loggedin ) {
+ if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
+ # generated css
+ $this->usercss = '@import "'.$this->makeUrl('-','action=raw&gen=css&smaxage=0&maxage=0').');'."\n";
+ // css preview
+ $this->usercss .= $wgRequest->getText('wpTextbox1');
+ } else {
+ # generated css
+ $this->usercss .= '@import "'.$this->makeUrl('-','action=raw&gen=css&smaxage=0').'";'."\n";
+ # import user stylesheet
+ $this->usercss .= '@import "'.
+ $this->makeUrl($this->userpage.'/'.$this->skinname.'.css', 'action=raw&ctype=text/css').'";'."\n";
+ }
+ if($wgTitle->isJsSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
+ # XXX: additional security check/prompt?
+ $this->userjsprev = $wgRequest->getText('wpTextbox1');
+ } else {
+ $this->userjs = $this->makeUrl($this->userpage.'/'.$this->skinname.'.js', 'action=raw&ctype=text/javascript');
+ }
}
- if($wgTitle->isJsSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
- # XXX: additional security check/prompt?
- $this->userjsprev = $wgRequest->getText('wpTextbox1');
- } else {
- $this->userjs = $this->makeUrl($this->userpage.'/'.$this->skinname.'.js', 'action=raw&ctype=text/javascript');
+ }
+ # returns css with user-specific options
+ function getUserStylesheet() {
+ global $wgUser, $wgRequest, $wgTitle, $wgLang, $wgSquidMaxage, $wgStylePath;
+ $action = $wgRequest->getText('action');
+ $maxage = $wgRequest->getText('maxage');
+ $s = "/* generated user stylesheet */\n";
+ if($wgLang->isRTL()) $s .= '@import "'.$wgStylePath.'/'.$this->skinname.'/rtl.css";'."\n";
+ $s .= '@import "'.
+ $this->makeNSUrl(ucfirst($this->skinname).'.css', 'action=raw&ctype=text/css&smaxage='.$wgSquidMaxage, NS_MEDIAWIKI)."\";\n";
+ if($wgUser->getID() != 0) {
+ if ( 1 == $wgUser->getOption( "underline" ) ) {
+ $s .= "a { text-decoration: underline; }\n";
+ } else {
+ $s .= "a { text-decoration: none; }\n";
+ }
+ }
+ if ( 1 != $wgUser->getOption( "highlightbroken" ) ) {
+ $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
}
+ if ( 1 == $wgUser->getOption( "justify" ) ) {
+ $s .= "#bodyContent { text-align: justify; }\n";
+ }
+ return $s;
+ }
+ function getUserJs() {
+ global $wgUser, $wgStylePath;
+ $s = "/* generated javascript */";
+ $s .= "var skin = '{$this->skinname}';\nvar stylepath = '{$wgStylePath}';";
+ $s .= '/* MediaWiki:'.ucfirst($this->skinname)." */\n";
+ $s .= wfMsg(ucfirst($this->skinname).'.js');
+ return $s;
}
+
}
class SkinDaVinci extends SkinPHPTal {
@@ -584,5 +598,12 @@
$this->skinname = "monobook";
}
}
+
+ class SkinMySkin extends SkinPHPTal {
+ function initPage( &$out ) {
+ SkinPHPTal::initPage( $out );
+ $this->skinname = "myskin";
+ }
+ }
?>
diff --git a/includes/SkinStandard.php b/includes/SkinStandard.php
index 929fc3e91827..ba367a370d85 100644
--- a/includes/SkinStandard.php
+++ b/includes/SkinStandard.php
@@ -18,12 +18,12 @@ class SkinStandard extends Skin {
function getUserStyles()
{
global $wgStylePath;
-
- $s = parent::getUserStyles();
+ $s = '';
if ( 3 == $this->qbSetting() ) { # Floating left
$s .= "<style type='text/css'>\n" .
"@import '{$wgStylePath}/quickbar.css';\n</style>\n";
}
+ $s .= parent::getUserStyles();
return $s;
}
diff --git a/includes/SpecialAllpages.php b/includes/SpecialAllpages.php
index 67246e447f01..ccac741ebd28 100644
--- a/includes/SpecialAllpages.php
+++ b/includes/SpecialAllpages.php
@@ -52,7 +52,7 @@ function indexShowToplevel()
# There's got to be a cleaner way to do this!
for( $i = 1; $i < $sections; $i++ ) {
$from = $i * $indexMaxperpage;
- $sql = "SELECT cur_title $fromwhere $order LIMIT $from,2";
+ $sql = "SELECT cur_title $fromwhere $order ".wfLimitResult(2,$from);
$res = wfQuery( $sql, DB_READ, $fname );
$s = wfFetchObject( $res );
@@ -66,7 +66,7 @@ function indexShowToplevel()
}
$from = $i * $indexMaxperpage;
- $sql = "SELECT cur_title $fromwhere $order LIMIT " . ($count-1) . ",1";
+ $sql = "SELECT cur_title $fromwhere $order ".wfLimitResult(1,$count-1);
$res = wfQuery( $sql, DB_READ, $fname );
$s = wfFetchObject( $res );
$outpoint = $s->cur_title;
diff --git a/includes/SpecialAncientpages.php b/includes/SpecialAncientpages.php
index 52bc0058b3b2..3aa93a54a47d 100644
--- a/includes/SpecialAncientpages.php
+++ b/includes/SpecialAncientpages.php
@@ -13,12 +13,14 @@ class AncientPagesPage extends QueryPage {
}
function getSQL() {
+ global $wgIsMySQL;
+ $use_index=$wgIsMySQL?"USE INDEX (cur_timestamp)":"";
return
"SELECT 'Ancientpages' as type,
cur_namespace as namespace,
cur_title as title,
UNIX_TIMESTAMP(cur_timestamp) as value
- FROM cur USE INDEX (cur_timestamp)
+ FROM cur $use_index
WHERE cur_namespace=0 AND cur_is_redirect=0";
}
diff --git a/includes/SpecialAsksql.php b/includes/SpecialAsksql.php
index 6c9c487e4faa..63fefb1a9672 100644
--- a/includes/SpecialAsksql.php
+++ b/includes/SpecialAsksql.php
@@ -1,4 +1,10 @@
<?php
+#
+# If enabled through $wgAllowSysopQueries = true, this class
+# let users with sysop right the possibility to make sql queries
+# against the cur table.
+# Heavy queries could slow down the database specially for the
+# biggest wikis.
function wfSpecialAsksql()
{
diff --git a/includes/SpecialCategories.php b/includes/SpecialCategories.php
index 1a3efca0ccee..6cc493e7ccdf 100644
--- a/includes/SpecialCategories.php
+++ b/includes/SpecialCategories.php
@@ -1,45 +1,44 @@
<?php
+require_once("QueryPage.php");
+
+class CategoriesPage extends QueryPage {
+
+ function getName() {
+ return "Categories";
+ }
+
+ function isExpensive() {
+ return false;
+ }
+
+ function getSQL() {
+ $NScat = NS_CATEGORY;
+ return "SELECT DISTINCT 'Categories' as type,
+ {$NScat} as namespace,
+ cl_to as title,
+ 1 as value
+ FROM categorylinks";
+ }
+
+ function sortDescending() {
+ return false;
+ }
+
+ function formatResult( $skin, $result ) {
+ global $wgLang;
+ $title = Title::makeTitle( NS_CATEGORY, $result->title );
+ return $skin->makeLinkObj( $title, $title->getText() );
+ }
+}
+
function wfSpecialCategories()
{
- global $wgUser, $wgOut , $wgLang;
-
- $sk = $wgUser->getSkin() ;
- $sc = "Special:Categories" ;
-
- # List all existant categories.
- # Note: this list could become *very large*
- $r = "<ol>\n" ;
- $sql = "SELECT cur_title FROM cur WHERE cur_namespace=".Namespace::getCategory() ;
- $res = wfQuery ( $sql, DB_READ ) ;
- while ( $x = wfFetchObject ( $res ) ) {
- $title =& Title::makeTitle( NS_CATEGORY, $x->cur_title );
- $r .= "<li>" ;
- $r .= $sk->makeKnownLinkObj ( $title, $title->getText() ) ;
- $r .= "</li>\n" ;
- }
- wfFreeResult ( $res ) ;
- $r .= "</ol>\n" ;
-
- $r .= "<hr />\n" ;
-
- # Links to category pages that haven't been created.
- # FIXME: This could be slow if there are a lot, but the title index should
- # make it reasonably snappy since we're using an index.
- $cat = wfStrencode( $wgLang->getNsText( NS_CATEGORY ) );
- $sql = "SELECT DISTINCT bl_to FROM brokenlinks WHERE bl_to LIKE \"{$cat}:%\"" ;
- $res = wfQuery ( $sql, DB_READ ) ;
- $r .= "<ol>\n" ;
- while ( $x = wfFetchObject ( $res ) ) {
- $title = Title::newFromDBkey( $x->bl_to );
- $r .= "<li>" ;
- $r .= $sk->makeBrokenLinkObj( $title, $title->getText() ) ;
- $r .= "</li>\n" ;
- }
- wfFreeResult ( $res ) ;
- $r .= "</ol>\n" ;
-
- $wgOut->addHTML ( $r ) ;
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $cap = new CategoriesPage();
+
+ return $cap->doQuery( $offset, $limit );
}
?>
diff --git a/includes/SpecialContributions.php b/includes/SpecialContributions.php
index ad9b5acb5e06..0dcd5ebfc3ae 100644
--- a/includes/SpecialContributions.php
+++ b/includes/SpecialContributions.php
@@ -2,7 +2,7 @@
function wfSpecialContributions( $par = "" )
{
- global $wgUser, $wgOut, $wgLang, $wgRequest;
+ global $wgUser, $wgOut, $wgLang, $wgRequest, $wgIsPg;
$fname = "wfSpecialContributions";
$sysop = $wgUser->isSysop();
@@ -21,23 +21,35 @@ function wfSpecialContributions( $par = "" )
$offlimit = $limit + $offset;
$querylimit = $offlimit + 1;
$hideminor = ($wgRequest->getVal( 'hideminor' ) ? 1 : 0);
+ $sk = $wgUser->getSkin();
+
+ $userCond = "";
$nt = Title::newFromURL( $target );
$nt->setNamespace( Namespace::getUser() );
- $sk = $wgUser->getSkin();
$id = User::idFromName( $nt->getText() );
if ( 0 == $id ) {
$ul = $nt->getText();
} else {
- $ul = $sk->makeLinkObj( $nt, $nt->getText() );
+ $ul = $sk->makeLinkObj( $nt, htmlspecialchars( $nt->getText() ) );
+ $userCond = "=" . $id;
}
$talk = $nt->getTalkPage();
if( $talk )
$ul .= " (" . $sk->makeLinkObj( $talk, $wgLang->getNsText(Namespace::getTalk(0)) ) . ")";
else
$ul .= "brrrp";
+
+ if ( $target == 'newbies' ) {
+ # View the contributions of all recently created accounts
+ $row = wfGetArray("user",array("max(user_id) as m"),false);
+ $userCond = ">" . ($row->m - $row->m / 100);
+ $ul = "";
+ $id = 0;
+ }
+
$wgOut->setSubtitle( wfMsg( "contribsub", $ul ) );
if ( $hideminor ) {
@@ -53,23 +65,24 @@ function wfSpecialContributions( $par = "" )
"&offset={$offset}&limit={$limit}&hideminor=1" );
}
- if ( 0 == $id ) {
- $sql = "SELECT cur_namespace,cur_title,cur_timestamp,cur_comment,cur_minor_edit,cur_is_new FROM cur " .
+ $oldtable=$wgIsPg?'"old"':'old';
+ if ( $userCond == "" ) {
+ $sql = "SELECT cur_namespace,cur_title,cur_timestamp,cur_comment,cur_minor_edit,cur_is_new,cur_user_text FROM cur " .
"WHERE cur_user_text='" . wfStrencode( $nt->getText() ) . "' {$cmq} " .
"ORDER BY inverse_timestamp LIMIT {$querylimit}";
$res1 = wfQuery( $sql, DB_READ, $fname );
- $sql = "SELECT old_namespace,old_title,old_timestamp,old_comment,old_minor_edit FROM old " .
+ $sql = "SELECT old_namespace,old_title,old_timestamp,old_comment,old_minor_edit,old_user_text FROM $oldtable " .
"WHERE old_user_text='" . wfStrencode( $nt->getText() ) . "' {$omq} " .
"ORDER BY inverse_timestamp LIMIT {$querylimit}";
$res2 = wfQuery( $sql, DB_READ, $fname );
} else {
- $sql = "SELECT cur_namespace,cur_title,cur_timestamp,cur_comment,cur_minor_edit,cur_is_new FROM cur " .
- "WHERE cur_user={$id} {$cmq} ORDER BY inverse_timestamp LIMIT {$querylimit}";
+ $sql = "SELECT cur_namespace,cur_title,cur_timestamp,cur_comment,cur_minor_edit,cur_is_new,cur_user_text FROM cur " .
+ "WHERE cur_user {$userCond} {$cmq} ORDER BY inverse_timestamp LIMIT {$querylimit}";
$res1 = wfQuery( $sql, DB_READ, $fname );
- $sql = "SELECT old_namespace,old_title,old_timestamp,old_comment,old_minor_edit FROM old " .
- "WHERE old_user={$id} {$omq} ORDER BY inverse_timestamp LIMIT {$querylimit}";
+ $sql = "SELECT old_namespace,old_title,old_timestamp,old_comment,old_minor_edit,old_user_text FROM $oldtable " .
+ "WHERE old_user {$userCond} {$omq} ORDER BY inverse_timestamp LIMIT {$querylimit}";
$res2 = wfQuery( $sql, DB_READ, $fname );
}
$nCur = wfNumRows( $res1 );
@@ -107,6 +120,8 @@ function wfSpecialContributions( $par = "" )
$comment =$obj1->cur_comment;
$me = $obj1->cur_minor_edit;
$isnew = $obj1->cur_is_new;
+ $usertext = $obj1->cur_user_text;
+
$obj1 = wfFetchObject( $res1 );
$topmark = true;
--$nCur;
@@ -116,6 +131,7 @@ function wfSpecialContributions( $par = "" )
$ts = $obj2->old_timestamp;
$comment =$obj2->old_comment;
$me = $obj2->old_minor_edit;
+ $usertext = $obj2->old_user_text;
$obj2 = wfFetchObject( $res2 );
$topmark = false;
@@ -123,7 +139,7 @@ function wfSpecialContributions( $par = "" )
--$nOld;
}
if( $n >= $offset )
- ucListEdit( $sk, $ns, $t, $ts, $topmark, $comment, ( $me > 0), $isnew );
+ ucListEdit( $sk, $ns, $t, $ts, $topmark, $comment, ( $me > 0), $isnew, $usertext );
}
$wgOut->addHTML( "</ul>\n" );
}
@@ -147,7 +163,7 @@ other users.
TODO: This would probably look a lot nicer in a table.
*/
-function ucListEdit( $sk, $ns, $t, $ts, $topmark, $comment, $isminor, $isnew )
+function ucListEdit( $sk, $ns, $t, $ts, $topmark, $comment, $isminor, $isnew, $target )
{
global $wgLang, $wgOut, $wgUser, $wgRequest;
$page = Title::makeName( $ns, $t );
@@ -162,7 +178,7 @@ function ucListEdit( $sk, $ns, $t, $ts, $topmark, $comment, $isminor, $isnew )
$sysop = $wgUser->isSysop();
if($sysop ) {
$extraRollback = $wgRequest->getBool( "bot" ) ? '&bot=1' : '';
- $target = $wgRequest->getText( 'target' );
+ # $target = $wgRequest->getText( 'target' );
$topmarktext .= " [". $sk->makeKnownLink( $page,
wfMsg( "rollbacklink" ),
"action=rollback&from=" . urlencode( $target ) . $extraRollback ) ."]";
diff --git a/includes/SpecialDeadendpages.php b/includes/SpecialDeadendpages.php
index 84641a5d51fd..a571d68388db 100644
--- a/includes/SpecialDeadendpages.php
+++ b/includes/SpecialDeadendpages.php
@@ -4,22 +4,26 @@ require_once( "QueryPage.php" );
class DeadendPagesPage extends PageQueryPage {
- function getName( ) {
- return "Deadendpages";
- }
+ function getName( ) {
+ return "Deadendpages";
+ }
- # LEFT JOIN is expensive
+ # LEFT JOIN is expensive
- function isExpensive( ) {
- return 1;
- }
+ function isExpensive( ) {
+ return 1;
+ }
+
+ function sortDescending() {
+ return false;
+ }
- function getSQL( $offset, $limit ) {
- return "SELECT cur_title as title, 0 as value " .
- "FROM cur LEFT JOIN links ON cur_id = l_from " .
- "WHERE l_from IS NULL " .
- "AND cur_namespace = 0 " .
- "AND cur_is_redirect = 0";
+ function getSQL() {
+ return "SELECT 'Deadendpages' as type, cur_namespace AS namespace, cur_title as title, cur_title AS value " .
+ "FROM cur LEFT JOIN links ON cur_id = l_from " .
+ "WHERE l_from IS NULL " .
+ "AND cur_namespace = 0 " .
+ "AND cur_is_redirect = 0";
}
}
diff --git a/includes/SpecialListadmins.php b/includes/SpecialListadmins.php
new file mode 100644
index 000000000000..8518c43eafb0
--- /dev/null
+++ b/includes/SpecialListadmins.php
@@ -0,0 +1,37 @@
+<?php
+#
+# This class is used to get a list of users flagged with "sysop"
+# right.
+
+require_once("QueryPage.php");
+
+class ListAdminsPage extends PageQueryPage {
+
+ function getName() {
+ return 'Listadmins';
+ }
+
+ function sortDescending() {
+ return false;
+ }
+
+ function getSQL() {
+ global $wgIsPg;
+ $usertable = $wgIsPg?'"user"':'user';
+ $userspace = Namespace::getUser();
+ return 'SELECT user_rights as type,'.$userspace.' as namespace,'.
+ 'user_name as title, user_name as value '.
+ "FROM $usertable ".
+ 'WHERE user_rights LIKE "%sysop%"';
+ }
+}
+
+function wfSpecialListadmins() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $sla = new ListAdminsPage();
+
+ return $sla->doQuery( $offset, $limit );
+}
+
+?>
diff --git a/includes/SpecialListusers.php b/includes/SpecialListusers.php
index f87852f48297..e74f2a23a920 100644
--- a/includes/SpecialListusers.php
+++ b/includes/SpecialListusers.php
@@ -1,38 +1,48 @@
<?php
+#
+# This class is used to get a list of user. The ones with specials
+# rights (sysop, bureaucrat, developer) will have them displayed
+# next to their names.
-function wfSpecialListusers()
-{
- global $wgUser, $wgOut, $wgLang;
+require_once("QueryPage.php");
- list( $limit, $offset ) = wfCheckLimits();
+class ListUsersPage extends QueryPage {
- $top = wfShowingResults( $offset, $limit );
- $wgOut->addHTML( "<p>{$top}\n" );
+ function getName() {
+ return "Listusers";
+ }
- $sl = wfViewPrevNext( $offset, $limit,
- $wgLang->specialPage( "Listusers" ) );
- $wgOut->addHTML( "<br />{$sl}</p>\n<ol start='" . ( $offset + 1 ) . "'>" );
+ function getSQL() {
+ global $wgIsPg;
+ $usertable = $wgIsPg?'"user"':'user';
+ $userspace = Namespace::getUser();
+ return "SELECT user_rights as type, $userspace as namespace, user_name as title, user_name as value FROM $usertable";
+ }
+
+ function sortDescending() {
+ return false;
+ }
- $sql = "SELECT user_name,user_rights FROM user ORDER BY " .
- "user_name LIMIT {$offset}, {$limit}";
- $res = wfQuery( $sql, DB_READ, "wfSpecialListusers" );
+ function formatResult( $skin, $result ) {
+ global $wgLang;
+ $name = $skin->makeKnownLink( $wgLang->getNsText($result->namespace) . ':' . $result->title, $result->title );
+ if( '' != $result->type ) {
+ $name .= ' (' .
+ $skin->makeKnownLink( wfMsg( "administrators" ), $result->type) .
+ ')';
+ }
+ return $name;
+ }
+}
- $sk = $wgUser->getSkin();
- while ( $s = wfFetchObject( $res ) ) {
- $n = $s->user_name;
- $r = $s->user_rights;
+function wfSpecialListusers() {
+ global $wgUser, $wgOut, $wgLang, $wgIsPg;
- $l = $sk->makeLink( $wgLang->getNsText(
- Namespace::getUser() ) . ":{$n}", $n );
+ list( $limit, $offset ) = wfCheckLimits();
- if ( "" != $r ) {
- $link = $sk->makeKnownLink( wfMsg( "administrators" ), $r );
- $l .= " ({$link})";
- }
- $wgOut->addHTML( "<li>{$l}</li>\n" );
- }
- wfFreeResult( $res );
- $wgOut->addHTML( "</ol>\n<p>{$sl}</p>\n" );
+ $slu = new ListUsersPage();
+
+ return $slu->doQuery( $offset, $limit );
}
?>
diff --git a/includes/SpecialLonelypages.php b/includes/SpecialLonelypages.php
index bd5286414c6f..ebb4f0b034ac 100644
--- a/includes/SpecialLonelypages.php
+++ b/includes/SpecialLonelypages.php
@@ -3,30 +3,28 @@
require_once( "QueryPage.php" );
class LonelyPagesPage extends PageQueryPage {
-
- function getName() {
- return "Lonelypages";
- }
-
- function isExpensive() {
- return 1;
- }
-
- function getSQL( $offset, $limit ) {
- return "SELECT cur_title FROM cur LEFT JOIN links ON " .
- "cur_id=l_to WHERE l_to IS NULL AND cur_namespace=0 AND " .
- "cur_is_redirect=0 ORDER BY cur_title LIMIT {$offset}, {$limit}";
- }
+ function getName() {
+ return "Lonelypages";
+ }
+
+ function isExpensive() {
+ return true;
+ }
+
+ function getSQL() {
+ return "SELECT 'Lonelypages' as type, cur_namespace AS namespace, cur_title AS title, cur_title AS value " .
+ "FROM cur LEFT JOIN links ON cur_id=l_to ".
+ "WHERE l_to IS NULL AND cur_namespace=0 AND cur_is_redirect=0";
+ }
}
-function wfSpecialLonelypages()
-{
- list( $limit, $offset ) = wfCheckLimits();
-
- $lpp = new LonelyPagesPage();
-
- return $lpp->doQuery( $offset, $limit );
+function wfSpecialLonelypages() {
+ list( $limit, $offset ) = wfCheckLimits();
+
+ $lpp = new LonelyPagesPage();
+
+ return $lpp->doQuery( $offset, $limit );
}
?>
diff --git a/includes/SpecialMakesysop.php b/includes/SpecialMakesysop.php
index 653f06256e60..a9564f167fb2 100644
--- a/includes/SpecialMakesysop.php
+++ b/includes/SpecialMakesysop.php
@@ -76,7 +76,7 @@ class MakesysopForm {
</td>
</tr>"
);
- /*
+
$makeburo = wfMsg( "setbureaucratflag" );
$wgOut->addHTML(
"<tr>
@@ -84,7 +84,7 @@ class MakesysopForm {
<input type=checkbox name=\"wpSetBureaucrat\" value=1>$makeburo
</td>
</tr>"
- );*/
+ );
if ( $wgUser->isDeveloper() ) {
$rights = wfMsg( "rights" );
diff --git a/includes/SpecialPage.php b/includes/SpecialPage.php
index 5b013bffe1fc..c8e97f2311d8 100644
--- a/includes/SpecialPage.php
+++ b/includes/SpecialPage.php
@@ -1,5 +1,5 @@
<?php
-
+global $wgSpecialPages;
$wgSpecialPages = array(
"Userlogin" => new UnlistedSpecialPage( "Userlogin" ),
"Userlogout" => new UnlistedSpecialPage( "Userlogout" ),
@@ -9,11 +9,18 @@ $wgSpecialPages = array(
"Upload" => new SpecialPage( "Upload" ),
"Imagelist" => new SpecialPage( "Imagelist" ),
"Listusers" => new SpecialPage( "Listusers" ),
+ "Listadmins" => new SpecialPage( "Listadmins" ),
"Statistics" => new SpecialPage( "Statistics" ),
"Randompage" => new SpecialPage( "Randompage" ),
"Lonelypages" => new SpecialPage( "Lonelypages" ),
- "Unusedimages" => new SpecialPage( "Unusedimages" ),
- "Popularpages" => new SpecialPage( "Popularpages" ),
+ "Unusedimages" => new SpecialPage( "Unusedimages" )
+);
+global $wgDisableCounters;
+if( !$wgDisableCounters )
+{
+ $wgSpecialPages["Popularpages"] = new SpecialPage( "Popularpages" );
+}
+$wgSpecialPages = array_merge($wgSpecialPages, array (
"Wantedpages" => new SpecialPage( "Wantedpages" ),
"Shortpages" => new SpecialPage( "Shortpages" ),
"Longpages" => new SpecialPage( "Longpages" ),
@@ -43,7 +50,7 @@ $wgSpecialPages = array(
"Import" => new SpecialPage( "Import", "sysop" ),
"Lockdb" => new SpecialPage( "Lockdb", "developer" ),
"Unlockdb" => new SpecialPage( "Unlockdb", "developer" )
-);
+));
class SpecialPage
{
diff --git a/includes/SpecialPreferences.php b/includes/SpecialPreferences.php
index 11696a02efa7..e060dcb06b52 100644
--- a/includes/SpecialPreferences.php
+++ b/includes/SpecialPreferences.php
@@ -14,7 +14,7 @@ class PreferencesForm {
var $mReset, $mPosted, $mToggles, $mSearchNs, $mRealName;
function PreferencesForm( &$request ) {
- global $wgLang;
+ global $wgLang, $wgAllowRealName;
$this->mQuickbar = $request->getVal( 'wpQuickbar' );
$this->mOldpass = $request->getVal( 'wpOldpass' );
@@ -27,7 +27,7 @@ class PreferencesForm {
$this->mMath = $request->getVal( 'wpMath' );
$this->mDate = $request->getVal( 'wpDate' );
$this->mUserEmail = $request->getVal( 'wpUserEmail' );
- $this->mRealName = $request->getVal( 'wpRealName' );
+ $this->mRealName = ($wgAllowRealName) ? $request->getVal( 'wpRealName' ) : '';
$this->mEmailFlag = $request->getCheck( 'wpEmailFlag' ) ? 1 : 0;
$this->mNick = $request->getVal( 'wpNick' );
$this->mSearch = $request->getVal( 'wpSearch' );
@@ -180,11 +180,11 @@ class PreferencesForm {
/* private */ function resetPrefs()
{
- global $wgUser, $wgLang;
+ global $wgUser, $wgLang, $wgAllowRealName;
$this->mOldpass = $this->mNewpass = $this->mRetypePass = "";
$this->mUserEmail = $wgUser->getEmail();
- $this->mRealName = $wgUser->getRealName();
+ $this->mRealName = ($wgAllowRealName) ? $wgUser->getRealName() : '';
if ( 1 == $wgUser->getOption( "disablemail" ) ) { $this->mEmailFlag = 1; }
else { $this->mEmailFlag = 0; }
$this->mNick = $wgUser->getOption( "nickname" );
@@ -265,7 +265,8 @@ class PreferencesForm {
/* private */ function mainPrefsForm( $err )
{
global $wgUser, $wgOut, $wgLang, $wgUseDynamicDates, $wgValidSkinNames;
-
+ global $wgAllowRealName;
+
$wgOut->setPageTitle( wfMsg( "preferences" ) );
$wgOut->setArticleRelated( false );
$wgOut->setRobotpolicy( "noindex,nofollow" );
@@ -277,6 +278,7 @@ class PreferencesForm {
$uid = $wgUser->getID();
$wgOut->addWikiText( wfMsg( "prefslogintext", $uname, $uid ) );
+ $wgOut->addWikiText( wfMsg('clearyourcache'));
$qbs = $wgLang->getQuickbarSettings();
$skinNames = $wgLang->getSkinNames();
@@ -301,12 +303,13 @@ class PreferencesForm {
$tbr = wfMsg( "rows" );
$tbc = wfMsg( "columns" );
$ltz = wfMsg( "localtime" );
+ $timezone = wfMsg( "timezonelegend" );
$tzt = wfMsg( "timezonetext" );
$tzo = wfMsg( "timezoneoffset" );
$tzGuess = wfMsg( "guesstimezone" );
$tzServerTime = wfMsg( "servertime" );
$yem = wfMsg( "youremail" );
- $yrn = wfMsg( "yourrealname" );
+ $yrn = ($wgAllowRealName) ? wfMsg( "yourrealname" ) : '';
$emf = wfMsg( "emailflag" );
$ynn = wfMsg( "yournick" );
$stt = wfMsg ( "stubthreshold" ) ;
@@ -332,12 +335,15 @@ class PreferencesForm {
$ps = $this->namespacesCheckboxes();
$wgOut->addHTML( "<fieldset>
- <legend>".wfMsg('prefs-personal')."</legend>
- <div><label>$yrn: <input type='text' name=\"wpRealName\" value=\"{$this->mRealName}\" size='20' /></label></div>
+ <legend>".wfMsg('prefs-personal')."</legend>");
+ if ($wgAllowRealName) {
+ $wgOut->addHTML("<div><label>$yrn: <input type='text' name=\"wpRealName\" value=\"{$this->mRealName}\" size='20' /></label></div>");
+ }
+ $wgOut->addHTML("
<div><label>$yem: <input type='text' name=\"wpUserEmail\" value=\"{$this->mUserEmail}\" size='20' /></label></div>
<div><label><input type='checkbox' $emfc value=\"1\" name=\"wpEmailFlag\" /> $emf</label></div>
<div><label>$ynn: <input type='text' name=\"wpNick\" value=\"{$this->mNick}\" size='12' /></label></div>\n" );
-
+
# Fields for changing password
#
$this->mOldpass = wfEscapeHTML( $this->mOldpass );
@@ -363,6 +369,7 @@ class PreferencesForm {
$wgOut->addHTML( "<div><label><input type='radio' name=\"wpQuickbar\"
value=\"$i\"$checked /> {$qbs[$i]}</label></div>\n" );
}
+ $wgOut->addHtml('<div class="prefsectiontip">'.wfMsg('qbsettingsnote').'</div>');
$wgOut->addHtml( "</fieldset>\n\n" );
# Skin setting
@@ -426,7 +433,7 @@ class PreferencesForm {
</fieldset>
<fieldset>
- <legend>$dateFormat</legend>
+ <legend>$timezone</legend>
<div><b>$tzServerTime:</b> $nowserver</div>
<div><b>$ltz:</b> $nowlocal</div>
<div><label>$tzo*: <input type='text' name=\"wpHourDiff\" value=\"{$this->mHourDiff}\" size='6' /></label></div>
diff --git a/includes/SpecialRandompage.php b/includes/SpecialRandompage.php
index a442623f1b18..bf6a7fa9a03e 100644
--- a/includes/SpecialRandompage.php
+++ b/includes/SpecialRandompage.php
@@ -1,16 +1,18 @@
<?php
+# $Id$
function wfSpecialRandompage()
{
- global $wgOut, $wgTitle, $wgArticle;
+ global $wgOut, $wgTitle, $wgArticle, $wgIsMySQL;
$fname = "wfSpecialRandompage";
wfSeedRandom();
$rand = mt_rand() / mt_getrandmax();
# interpolation and sprintf() can muck up with locale-specific decimal separator
$randstr = number_format( $rand, 12, ".", "" );
+ $use_index=$wgIsMySQL?"USE INDEX (cur_random)":"";
$sqlget = "SELECT cur_id,cur_title
- FROM cur USE INDEX (cur_random)
+ FROM cur $use_index
WHERE cur_namespace=0 AND cur_is_redirect=0
AND cur_random>$randstr
ORDER BY cur_random
diff --git a/includes/SpecialRecentchanges.php b/includes/SpecialRecentchanges.php
index 127678528581..4470c7622c2b 100644
--- a/includes/SpecialRecentchanges.php
+++ b/includes/SpecialRecentchanges.php
@@ -111,11 +111,11 @@ function wfSpecialRecentchanges( $par )
} else {
$note = wfMsg( "rcnote", $wgLang->formatNum( $limit ), $wgLang->formatNum( $days ) );
}
- $wgOut->addHTML( "\n<hr/>\n{$note}\n<br/>" );
+ $wgOut->addHTML( "\n<hr />\n{$note}\n<br />" );
$note = rcDayLimitLinks( $days, $limit, "Recentchanges", $hideparams, false, $minorLink, $botLink, $liuLink );
- $note .= "<br/>\n" . wfMsg( "rclistfrom",
+ $note .= "<br />\n" . wfMsg( "rclistfrom",
$sk->makeKnownLink( $wgLang->specialPage( "Recentchanges" ),
$wgLang->timeanddate( $now, true ), "{$hideparams}&from=$now" ) );
diff --git a/includes/SpecialShortpages.php b/includes/SpecialShortpages.php
index 560b02b8c1af..c3eafc41187f 100644
--- a/includes/SpecialShortpages.php
+++ b/includes/SpecialShortpages.php
@@ -1,4 +1,8 @@
<?php
+#
+# SpecialShortpages extends QueryPage. It is used to return the shortest
+# pages in the database.
+#
require_once("QueryPage.php");
@@ -34,8 +38,7 @@ class ShortPagesPage extends QueryPage {
}
}
-function wfSpecialShortpages()
-{
+function wfSpecialShortpages() {
list( $limit, $offset ) = wfCheckLimits();
$spp = new ShortPagesPage();
diff --git a/includes/SpecialStatistics.php b/includes/SpecialStatistics.php
index a6433aaeb6a9..b842e52525f6 100644
--- a/includes/SpecialStatistics.php
+++ b/includes/SpecialStatistics.php
@@ -2,7 +2,7 @@
function wfSpecialStatistics()
{
- global $wgUser, $wgOut, $wgLang;
+ global $wgUser, $wgOut, $wgLang, $wgIsPg;
$fname = "wfSpecialStatistics";
$wgOut->addHTML( "<h2>" . wfMsg( "sitestats" ) . "</h2>\n" );
@@ -31,12 +31,13 @@ function wfSpecialStatistics()
$wgOut->addWikiText( $text );
$wgOut->addHTML( "<h2>" . wfMsg( "userstats" ) . "</h2>\n" );
- $sql = "SELECT COUNT(user_id) AS total FROM user";
+ $usertable=$wgIsPg?'"user"':'user';
+ $sql = "SELECT COUNT(user_id) AS total FROM $usertable";
$res = wfQuery( $sql, DB_READ, $fname );
$row = wfFetchObject( $res );
$total = $row->total;
- $sql = "SELECT COUNT(user_id) AS total FROM user " .
+ $sql = "SELECT COUNT(user_id) AS total FROM $usertable " .
"WHERE user_rights LIKE '%sysop%'";
$res = wfQuery( $sql, DB_READ, $fname );
$row = wfFetchObject( $res );
diff --git a/includes/SpecialUndelete.php b/includes/SpecialUndelete.php
index 9f2f8e2963e6..e504b31a9edc 100644
--- a/includes/SpecialUndelete.php
+++ b/includes/SpecialUndelete.php
@@ -79,7 +79,8 @@ class UndeleteForm {
if(!preg_match("/[0-9]{14}/",$timestamp)) return 0;
$sql = "SELECT ar_text,ar_flags FROM archive ".
- "WHERE ar_namespace={$namespace} AND ar_title=\"{$title}\" AND ar_timestamp={$timestamp}";
+ "WHERE ar_namespace={$namespace} AND ar_title='" .
+ wfStrencode( $title ) . "' AND ar_timestamp='" . wfStrencode( $timestamp ) ."'";
$ret = wfQuery( $sql, DB_READ, $fname );
$row = wfFetchObject( $ret );
@@ -97,8 +98,8 @@ class UndeleteForm {
$wgOut->setPagetitle( wfMsg( "undeletepage" ) );
# Get text of first revision
- $sql = "SELECT ar_text FROM archive WHERE ar_namespace={$namespace} AND ar_title=\"{$title}\"
- ORDER BY ar_timestamp DESC LIMIT 1";
+ $sql = "SELECT ar_text FROM archive WHERE ar_namespace={$namespace} AND ar_title='" .
+ wfStrencode( $title ) . "' ORDER BY ar_timestamp DESC LIMIT 1";
$ret = wfQuery( $sql, DB_READ );
if( wfNumRows( $ret ) == 0 ) {
@@ -110,8 +111,8 @@ class UndeleteForm {
# Get remaining revisions
$sql = "SELECT ar_minor_edit,ar_timestamp,ar_user,ar_user_text,ar_comment
- FROM archive WHERE ar_namespace={$namespace} AND ar_title=\"{$title}\"
- ORDER BY ar_timestamp DESC";
+ FROM archive WHERE ar_namespace={$namespace} AND ar_title='" . wfStrencode( $title ) .
+ "' ORDER BY ar_timestamp DESC";
$ret = wfQuery( $sql, DB_READ );
# Ditch first row
$row = wfFetchObject( $ret );
@@ -126,7 +127,8 @@ class UndeleteForm {
<input type=submit name=\"restore\" value=\"".wfMsg("undeletebtn")."\">
</form>");
- $log = wfGetSQL("cur", "cur_text", "cur_namespace=4 AND cur_title=\"".wfMsg("dellogpage")."\"" );
+ $log = wfGetSQL("cur", "cur_text", "cur_namespace=4 AND cur_title='".
+ wfStrencode( wfMsg("dellogpage") ) . "'" );
if(preg_match("/^(.*".
preg_quote( ($namespace ? ($wgLang->getNsText($namespace) . ":") : "")
. str_replace("_", " ", $title), "/" ).".*)$/m", $log, $m)) {
@@ -140,7 +142,7 @@ class UndeleteForm {
$sk->makeKnownLink( $wgLang->specialPage( "Undelete" ),
$wgLang->timeanddate( $row->ar_timestamp, true ),
"target=" . urlencode($this->mTarget) . "&timestamp={$row->ar_timestamp}" ) . " " .
- ". . {$row->ar_user_text}" .
+ ". . " . htmlspecialchars( $row->ar_user_text ) .
" <i>(" . htmlspecialchars($row->ar_comment) . "</i>)\n");
}
@@ -160,7 +162,7 @@ class UndeleteForm {
$wgOut->fatalError( wfMsg( "cannotundelete" ) );
return;
}
- $t = addslashes($title);
+ $t = wfStrencode($title);
# Move article and history from the "archive" table
$sql = "SELECT COUNT(*) AS count FROM cur WHERE cur_namespace={$namespace} AND cur_title='{$t}'";
diff --git a/includes/SpecialUnusedimages.php b/includes/SpecialUnusedimages.php
index 09075f5be1e2..4bc8d7bbf886 100644
--- a/includes/SpecialUnusedimages.php
+++ b/includes/SpecialUnusedimages.php
@@ -8,7 +8,7 @@ function wfSpecialUnusedimages() {
$sql = "SELECT img_name,img_user,img_user_text,img_timestamp,img_description " .
"FROM image LEFT JOIN imagelinks ON img_name=il_to WHERE il_to IS NULL " .
- "ORDER BY img_timestamp LIMIT {$offset}, {$limit}";
+ "ORDER BY img_timestamp ".wfLimitResult($limit,$offset);
$res = wfQuery( $sql, DB_READ, $fname );
$sk = $wgUser->getSkin();
diff --git a/includes/SpecialUpload.php b/includes/SpecialUpload.php
index eeff3989881d..f9dfebd824c9 100644
--- a/includes/SpecialUpload.php
+++ b/includes/SpecialUpload.php
@@ -73,13 +73,14 @@ class UploadForm {
global $wgUser, $wgOut, $wgLang;
global $wgUploadDirectory;
global $wgSavedFile, $wgUploadOldVersion;
- global $wgUseCopyrightUpload;
+ global $wgUseCopyrightUpload, $wgCheckCopyrightUpload;
global $wgCheckFileExtensions, $wgStrictFileExtensions;
- global $wgFileExtensions, $wgFileBlacklist;
+ global $wgFileExtensions, $wgFileBlacklist, $wgUploadSizeWarning;
if ( $wgUseCopyrightUpload ) {
$this->mUploadAffirm = 1;
- if ( trim ( $this->mUploadCopyStatus ) == "" || trim ( $this->mUploadSource ) == "" ) {
+ if ($wgCheckCopyrightUpload &&
+ (trim ( $this->mUploadCopyStatus ) == "" || trim ( $this->mUploadSource ) == "" )) {
$this->mUploadAffirm = 0;
}
}
@@ -106,6 +107,7 @@ class UploadForm {
return;
}
$nt = Title::newFromText( $basename );
+ $nt->setNamespace( Namespace::getImage() );
$this->mUploadSaveName = $nt->getDBkey();
/* Don't allow users to override the blacklist */
@@ -115,19 +117,31 @@ class UploadForm {
}
$this->saveUploadedFile( $this->mUploadSaveName, $this->mUploadTempName );
- if ( ( ! $this->mIgnoreWarning ) &&
- ( 0 != strcmp( ucfirst( $basename ), $this->mUploadSaveName ) ) ) {
- return $this->uploadWarning( wfMsg( "badfilename", $this->mUploadSaveName ) );
- }
+ if ( !$nt->userCanEdit() ) {
+ return $this->uploadError( wfMsg( "protectedpage" ) );
+ }
- if ( $wgCheckFileExtensions ) {
- if ( ( ! $this->mIgnoreWarning ) &&
- ( ! $this->checkFileExtension( $ext, $wgFileExtensions ) ) ) {
- return $this->uploadWarning( wfMsg( "badfiletype", $ext ) );
+ if ( ! $this->mIgnoreWarning ) {
+ $warning = '';
+ if( 0 != strcmp( ucfirst( $basename ), $this->mUploadSaveName ) ) {
+ $warning .= '<li>'.wfMsg( "badfilename", $this->mUploadSaveName ).'</li>';
}
- }
- if ( ( ! $this->mIgnoreWarning ) && ( $this->mUploadSize > 150000 ) ) {
- return $this->uploadWarning( wfMsg( "largefile" ) );
+
+ if ( $wgCheckFileExtensions ) {
+ if ( ! $this->checkFileExtension( $ext, $wgFileExtensions ) ) {
+ $warning .= '<li>'.wfMsg( "badfiletype", $ext ).'</li>';
+ }
+ }
+ if ( $wgUploadSizeWarning && ( $this->mUploadSize > $wgUploadSizeWarning ) ) {
+ $warning .= '<li>'.wfMsg( "largefile" ).'</li>';
+ }
+ if( $nt->getArticleID() ) {
+ $sk = $wgUser->getSkin();
+ $dname = $wgLang->getNsText( Namespace::getImage() ) . ":{$this->mUploadSaveName}";
+ $dlink = $sk->makeKnownLink( $dname, $dname );
+ $warning .= '<li>'.wfMsg( "fileexists", $dlink ).'</li>';
+ }
+ if($warning != '') return $this->uploadWarning($warning);
}
}
if ( !is_null( $this->mUploadOldVersion ) ) {
@@ -220,7 +234,7 @@ class UploadForm {
$sub = wfMsg( "uploadwarning" );
$wgOut->addHTML( "<h2>{$sub}</h2>\n" );
- $wgOut->addHTML( "<h4><font color=red>{$warning}</font></h4>\n" );
+ $wgOut->addHTML( "<ul class='warning'>{$warning}</ul><br/>\n" );
$save = wfMsg( "savefile" );
$reupload = wfMsg( "reupload" );
diff --git a/includes/SpecialUserlogin.php b/includes/SpecialUserlogin.php
index c950ed5f150a..700cf6cf49e0 100644
--- a/includes/SpecialUserlogin.php
+++ b/includes/SpecialUserlogin.php
@@ -20,7 +20,7 @@ class LoginForm {
var $mLoginattempt, $mRemember, $mEmail;
function LoginForm( &$request ) {
- global $wgLang;
+ global $wgLang, $wgAllowRealName;
$this->mName = $request->getText( 'wpName' );
$this->mPassword = $request->getText( 'wpPassword' );
@@ -35,8 +35,12 @@ class LoginForm {
$this->mAction = $request->getVal( 'action' );
$this->mRemember = $request->getCheck( 'wpRemember' );
$this->mEmail = $request->getText( 'wpEmail' );
- $this->mRealName = $request->getText( 'wpRealName' );
-
+ if ($wgAllowRealName) {
+ $this->mRealName = $request->getText( 'wpRealName' );
+ } else {
+ $this->mRealName = '';
+ }
+
# When switching accounts, it sucks to get automatically logged out
if( $this->mReturnto == $wgLang->specialPage( "Userlogout" ) ) {
$this->mReturnto = "";
@@ -122,6 +126,19 @@ class LoginForm {
{
global $wgUser, $wgOut;
global $wgMaxNameChars;
+ global $wgMemc, $wgAccountCreationThrottle, $wgDBname, $wgIP;
+
+ if ( $wgAccountCreationThrottle ) {
+ $key = "$wgDBname:acctcreate:ip:$wgIP";
+ $value = $wgMemc->incr( $key );
+ if ( !$value ) {
+ $wgMemc->set( $key, 1, 86400 );
+ }
+ if ( $value > $wgAccountCreationThrottle ) {
+ $this->throttleHit( $wgAccountCreationThrottle );
+ return;
+ }
+ }
if (!$wgUser->isAllowedToCreateAccount()) {
$this->userNotPrivilegedMessage();
@@ -301,7 +318,7 @@ class LoginForm {
/* private */ function mainLoginForm( $err )
{
global $wgUser, $wgOut, $wgLang;
- global $wgDBname;
+ global $wgDBname, $wgAllowRealName;
$le = wfMsg( "loginerror" );
$yn = wfMsg( "yourname" );
@@ -313,7 +330,11 @@ class LoginForm {
$ca = wfMsg( "createaccount" );
$cam = wfMsg( "createaccountmail" );
$ye = wfMsg( "youremail" );
- $yrn = wfMsg( "yourrealname" );
+ if ($wgAllowRealName) {
+ $yrn = wfMsg( "yourrealname" );
+ } else {
+ $yrn = '';
+ }
$efl = wfMsg( "emailforlost" );
$mmp = wfMsg( "mailmypassword" );
$endText = wfMsg( "loginend" );
@@ -401,20 +422,23 @@ class LoginForm {
<td align='right'>$ye:</td>
<td align='left'>
<input tabindex='6' type='text' name=\"wpEmail\" value=\"{$encEmail}\" size='20' />
- </td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td align='right'>$yrn:</td>
- <td align='left'>
- <input tabindex='6' type='text' name=\"wpRealName\" value=\"{$encRealName}\" size='20' />
- </td>
- <td align='left'>
+ </td>");
+
+ if ($wgAllowRealName) {
+ $wgOut->addHTML("<td>&nbsp;</td>
+ </tr><tr>
+ <td align='right'>$yrn:</td>
+ <td align='left'>
+ <input tabindex='6' type='text' name=\"wpRealName\" value=\"{$encRealName}\" size='20' />
+ </td>");
+ }
+
+ $wgOut->addHTML("<td align='left'>
<input tabindex='7' type='submit' name=\"wpCreateaccount\" value=\"{$ca}\" />
$cambutton
</td></tr>");
}
-
+
$wgOut->addHTML("
<tr><td colspan='3'>&nbsp;</td></tr><tr>
<td colspan='3' align='left'>
@@ -457,5 +481,11 @@ class LoginForm {
return $this->successfulLogin( wfMsg( "loginsuccess", $wgUser->getName() ) );
}
}
+
+ /* private */ function throttleHit( $limit ) {
+ global $wgOut;
+
+ $wgOut->addWikiText( wfMsg( 'acct_creation_throttle_hit', $limit ) );
+ }
}
?>
diff --git a/includes/SpecialWatchlist.php b/includes/SpecialWatchlist.php
index 619dc38445f9..806eff0e9673 100644
--- a/includes/SpecialWatchlist.php
+++ b/includes/SpecialWatchlist.php
@@ -5,7 +5,7 @@ require_once( "WatchedItem.php" );
function wfSpecialWatchlist()
{
global $wgUser, $wgOut, $wgLang, $wgTitle, $wgMemc;
- global $wgUseWatchlistCache, $wgWLCacheTimeout, $wgDBname;
+ global $wgUseWatchlistCache, $wgWLCacheTimeout, $wgDBname, $wgIsMySQL;
global $days, $limit, $target; # From query string
$fname = "wfSpecialWatchlist";
@@ -102,10 +102,14 @@ function wfSpecialWatchlist()
$sk = $wgUser->getSkin();
while( $s = wfFetchObject( $res ) ) {
$t = Title::makeTitle( $s->wl_namespace, $s->wl_title );
- $t = $t->getPrefixedText();
- $wgOut->addHTML( "<li><input type='checkbox' name='id[]' value=\"" . htmlspecialchars($t) . "\" />" .
- $sk->makeKnownLink( $t, $t ) .
- "</li>\n" );
+ if( is_null( $t ) ) {
+ $wgOut->addHTML( '<!-- bad title "' . htmlspecialchars( $s->wl_title ) . '" in namespace ' . IntVal( $s->wl_namespace ) . " -->\n" );
+ } else {
+ $t = $t->getPrefixedText();
+ $wgOut->addHTML( "<li><input type='checkbox' name='id[]' value=\"" . htmlspecialchars($t) . "\" />" .
+ $sk->makeKnownLink( $t, $t ) .
+ "</li>\n" );
+ }
}
$wgOut->addHTML( "</ul>\n" .
"<input type='submit' name='remove' value='" .
@@ -137,11 +141,11 @@ function wfSpecialWatchlist()
$wgLang->formatNum( $nitems ), $wgLang->formatNum( $npages ), $y,
$specialTitle->escapeLocalUrl( "magic=yes" ) ) . "</i><br />\n" );
-
+ $use_index=$wgIsMySQL?"USE INDEX ($x)":"";
$sql = "SELECT
cur_namespace,cur_title,cur_comment, cur_id,
cur_user,cur_user_text,cur_timestamp,cur_minor_edit,cur_is_new
- FROM watchlist,cur USE INDEX ($x)
+ FROM watchlist,cur $use_index
WHERE wl_user=$uid
AND $z
AND wl_title=cur_title
diff --git a/includes/SpecialWhatlinkshere.php b/includes/SpecialWhatlinkshere.php
index 900f9e7db294..d8770bb4383a 100644
--- a/includes/SpecialWhatlinkshere.php
+++ b/includes/SpecialWhatlinkshere.php
@@ -27,7 +27,7 @@ function wfSpecialWhatlinkshere($par = NULL)
$sk = $wgUser->getSkin();
$isredir = " (" . wfMsg( "isredirect" ) . ")\n";
- $wgOut->addHTML("&lt; ".$sk->makeKnownLinkObj($nt, "", "redirect=no" )."<br/>\n");
+ $wgOut->addHTML("&lt; ".$sk->makeKnownLinkObj($nt, "", "redirect=no" )."<br />\n");
if ( 0 == $id ) {
$sql = "SELECT cur_id,cur_namespace,cur_title,cur_is_redirect FROM brokenlinks,cur WHERE bl_to='" .
diff --git a/includes/Title.php b/includes/Title.php
index 255cc157bc38..35ae3e839102 100644
--- a/includes/Title.php
+++ b/includes/Title.php
@@ -88,13 +88,13 @@ class Title {
# From a URL-encoded title
/* static */ function newFromURL( $url )
{
- global $wgLang, $wgServer;
+ global $wgLang, $wgServer, $wgIsMySQL, $wgIsPg;
$t = new Title();
- $s = urldecode( $url ); # This is technically wrong, as anything
- # we've gotten is already decoded by PHP.
- # Kept for backwards compatibility with
- # buggy URLs we had for a while...
- $s = $url;
+
+ # For compatibility with old buggy URLs. "+" is not valid in titles,
+ # but some URLs used it as a space replacement and they still come
+ # from some external search tools.
+ $s = str_replace( "+", " ", $url );
# For links that came from outside, check for alternate/legacy
# character encoding.
@@ -109,14 +109,20 @@ class Title {
$t->mDbkeyform = str_replace( " ", "_", $s );
if( $t->secureAndSplit() ) {
-
# check that lenght of title is < cur_title size
- $sql = "SHOW COLUMNS FROM cur LIKE \"cur_title\";";
- $cur_title_object = wfFetchObject(wfQuery( $sql, DB_READ ));
+ if ($wgIsMySQL) {
+ $sql = "SHOW COLUMNS FROM cur LIKE \"cur_title\";";
+ $cur_title_object = wfFetchObject(wfQuery( $sql, DB_READ ));
- preg_match( "/\((.*)\)/", $cur_title_object->Type, $cur_title_size);
+ preg_match( "/\((.*)\)/", $cur_title_object->Type, $cur_title_type);
+ $cur_title_size=$cur_title_type[1];
+ } else {
+ /* midom:FIXME pg_field_type does not return varchar length
+ assume 255 */
+ $cur_title_size=255;
+ }
- if (strlen($t->mDbkeyform) > $cur_title_size[1] ) {
+ if (strlen($t->mDbkeyform) > $cur_title_size ) {
return NULL;
}
@@ -182,11 +188,12 @@ class Title {
# Missing characters:
# * []|# Needed for link syntax
# * % and + are corrupted by Apache when they appear in the path
+ # * % seems to work though
#
# Theoretically 0x80-0x9F of ISO 8859-1 should be disallowed, but
# this breaks interlanguage links
- $set = " !\"$&'()*,\\-.\\/0-9:;<=>?@A-Z\\\\^_`a-z{}~\\x80-\\xFF";
+ $set = " %!\"$&'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z{}~\\x80-\\xFF";
return $set;
}
@@ -228,8 +235,7 @@ class Title {
# The URL contains $1, which is replaced by the title
function getInterwikiLink( $key )
{
- global $wgMemc, $wgDBname, $wgInterwikiExpiry;
- static $wgTitleInterwikiCache = array();
+ global $wgMemc, $wgDBname, $wgInterwikiExpiry, $wgTitleInterwikiCache;
$k = "$wgDBname:interwiki:$key";
@@ -369,9 +375,6 @@ class Title {
$n = $wgLang->getNsText( $this->mNamespace );
if ( "" != $n ) { $n .= ":"; }
$u = str_replace( "$1", $n . $this->mUrlform, $p );
- if ( "" != $this->mFragment ) {
- $u .= "#" . wfUrlencode( $this->mFragment );
- }
return $u;
}
@@ -486,15 +489,20 @@ class Title {
# Can $wgUser edit this page?
function userCanEdit()
{
-
+ global $wgUser;
if ( -1 == $this->mNamespace ) { return false; }
+ if ( NS_MEDIAWIKI == $this->mNamespace && !$wgUser->isSysop() ) { return false; }
# if ( 0 == $this->getArticleID() ) { return false; }
if ( $this->mDbkeyform == "_" ) { return false; }
+ # protect global styles and js
+ if ( NS_MEDIAWIKI == $this->mNamespace
+ && preg_match("/\\.(css|js)$/", $this->mTextform )
+ && !$wgUser->isSysop() )
+ { return false; }
//if ( $this->isCssJsSubpage() and !$this->userCanEditCssJsSubpage() ) { return false; }
# protect css/js subpages of user pages
# XXX: this might be better using restrictions
# XXX: Find a way to work around the php bug that prevents using $this->userCanEditCssJsSubpage() from working
- global $wgUser;
if( Namespace::getUser() == $this->mNamespace
and preg_match("/\\.(css|js)$/", $this->mTextform )
and !$wgUser->isSysop()
@@ -520,7 +528,7 @@ class Title {
if( in_array( $name, $wgWhitelistRead ) ) return true;
# Compatibility with old settings
- if( $this->getNamespace() == NS_ARTICLE ) {
+ if( $this->getNamespace() == NS_MAIN ) {
if( in_array( ":" . $name, $wgWhitelistRead ) ) return true;
}
return false;
@@ -638,6 +646,7 @@ class Title {
# Initialisation
if ( $imgpre === false ) {
$imgpre = ":" . $wgLang->getNsText( Namespace::getImage() ) . ":";
+ # % is needed as well
$rxTc = "/[^" . Title::legalChars() . "]/";
}
@@ -668,7 +677,7 @@ class Title {
$this->mNamespace = NS_MAIN;
} else {
# Namespace or interwiki prefix
- if ( preg_match( "/^((?:i|x|[a-z]{2,3})(?:-[a-z0-9]+)?|[A-Za-z0-9_\\x80-\\xff]+?)_*:_*(.*)$/", $t, $m ) ) {
+ if ( preg_match( "/^(.+?)_*:_*(.*)$/", $t, $m ) ) {
#$p = strtolower( $m[1] );
$p = $m[1];
$lowerNs = strtolower( $p );
@@ -716,8 +725,13 @@ class Title {
return false;
}
- # "." and ".." conflict with the directories of those names
- if ( $r === "." || $r === ".." ) {
+ # "." and ".." conflict with the directories of those namesa
+ if ( strpos( $r, "." ) !== false &&
+ ( $r === "." || $r === ".." ||
+ strpos( $r, "./" ) === 0 ||
+ strpos( $r, "/./" !== false ) ||
+ strpos( $r, "/../" !== false ) ) )
+ {
return false;
}
@@ -756,9 +770,10 @@ class Title {
$retVal = array();
if ( wfNumRows( $res ) ) {
while ( $row = wfFetchObject( $res ) ) {
- $titleObj = Title::makeTitle( $row->cur_namespace, $row->cur_title );
- $wgLinkCache->addGoodLink( $row->cur_id, $titleObj->getPrefixedDBkey() );
- $retVal[] = $titleObj;
+ if ( $titleObj = Title::makeTitle( $row->cur_namespace, $row->cur_title ) ) {
+ $wgLinkCache->addGoodLink( $row->cur_id, $titleObj->getPrefixedDBkey() );
+ $retVal[] = $titleObj;
+ }
}
}
wfFreeResult( $res );
@@ -777,7 +792,7 @@ class Title {
if ( wfNumRows( $res ) ) {
while ( $row = wfFetchObject( $res ) ) {
$titleObj = Title::makeTitle( $row->cur_namespace, $row->cur_title );
- $wgLinkCache->addGoodLink( $titleObj->getPrefixedDBkey(), $row->cur_id );
+ $wgLinkCache->addGoodLink( $row->cur_id, $titleObj->getPrefixedDBkey() );
$retVal[] = $titleObj;
}
}
@@ -927,7 +942,7 @@ class Title {
$fname
);
- RecentChange::notifyMove( $now, $this, $nt, $wgUser, $comment );
+ RecentChange::notifyMoveOverRedirect( $now, $this, $nt, $wgUser, $comment );
# Swap links
@@ -935,34 +950,51 @@ class Title {
$linksToOld = $this->getLinksTo();
$linksToNew = $nt->getLinksTo();
- # Make function to convert Titles to IDs
- $titleToID = create_function('$t', 'return $t->getArticleID();');
-
- # Reassign links to old title
- if ( count( $linksToOld ) ) {
- $sql = "UPDATE links SET l_to=$newid WHERE l_from IN (";
- $sql .= implode( ",", array_map( $titleToID, $linksToOld ) );
- $sql .= ")";
- wfQuery( $sql, DB_WRITE, $fname );
- }
-
- # Reassign links to new title
- if ( count( $linksToNew ) ) {
- $sql = "UPDATE links SET l_to=$oldid WHERE l_from IN (";
- $sql .= implode( ",", array_map( $titleToID, $linksToNew ) );
- $sql .= ")";
+ # Delete them all
+ $sql = "DELETE FROM links WHERE l_to=$oldid OR l_to=$newid";
+ wfQuery( $sql, DB_WRITE, $fname );
+
+ # Reinsert
+ if ( count( $linksToOld ) || count( $linksToNew )) {
+ $sql = "INSERT INTO links (l_from,l_to) VALUES ";
+ $first = true;
+
+ # Insert links to old title
+ foreach ( $linksToOld as $linkTitle ) {
+ if ( $first ) {
+ $first = false;
+ } else {
+ $sql .= ",";
+ }
+ $id = $linkTitle->getArticleID();
+ $sql .= "($id,$newid)";
+ }
+
+ # Insert links to new title
+ foreach ( $linksToNew as $linkTitle ) {
+ if ( $first ) {
+ $first = false;
+ } else {
+ $sql .= ",";
+ }
+ $id = $linkTitle->getArticleID();
+ $sql .= "($id, $oldid)";
+ }
+
wfQuery( $sql, DB_WRITE, $fname );
}
- # Note: the insert below must be after the updates above!
-
# Now, we record the link from the redirect to the new title.
# It should have no other outgoing links...
$sql = "DELETE FROM links WHERE l_from={$newid}";
wfQuery( $sql, DB_WRITE, $fname );
$sql = "INSERT INTO links (l_from,l_to) VALUES ({$newid},{$oldid})";
wfQuery( $sql, DB_WRITE, $fname );
-
+
+ # Clear linkscc
+ LinkCache::linksccClearLinksTo( $oldid );
+ LinkCache::linksccClearLinksTo( $newid );
+
# Purge squid
if ( $wgUseSquid ) {
$urls = array_merge( $nt->getSquidURLs(), $this->getSquidURLs() );
@@ -1029,14 +1061,16 @@ class Title {
), $fname
);
- # Miscellaneous updates
+ # Record in RC
+ RecentChange::notifyMoveToNew( $now, $this, $nt, $wgUser, $comment );
- RecentChange::notifyMove( $now, $this, $nt, $wgUser, $comment );
+ # Purge squid and linkscc as per article creation
Article::onArticleCreate( $nt );
# Any text links to the old title must be reassigned to the redirect
$sql = "UPDATE links SET l_to={$newid} WHERE l_to={$oldid}";
wfQuery( $sql, DB_WRITE, $fname );
+ LinkCache::linksccClearLinksTo( $oldid );
# Record the just-created redirect's linking to the page
$sql = "INSERT INTO links (l_from,l_to) VALUES ({$newid},{$oldid})";
@@ -1140,5 +1174,84 @@ class Title {
return true;
}
+ # Get categories to wich belong this title and return an array of
+ # categories names.
+ function getParentCategories( )
+ {
+ global $wgLang,$wgUser;
+
+ #$titlekey = wfStrencode( $this->getArticleID() );
+ $titlekey = $this->getArticleId();
+ $cns = Namespace::getCategory();
+ $sk =& $wgUser->getSkin();
+ $parents = array();
+
+ # get the parents categories of this title from the database
+ $sql = "SELECT DISTINCT cur_id FROM cur,categorylinks
+ WHERE cl_from='$titlekey' AND cl_to=cur_title AND cur_namespace='$cns'
+ ORDER BY cl_sortkey" ;
+ $res = wfQuery ( $sql, DB_READ ) ;
+
+ if(wfNumRows($res) > 0) {
+ while ( $x = wfFetchObject ( $res ) ) $data[] = $x ;
+ wfFreeResult ( $res ) ;
+ } else {
+ $data = '';
+ }
+ return $data;
+ }
+
+ # will get the parents and grand-parents
+ # TODO : not sure what's happening when a loop happen like:
+ # Encyclopedia > Astronomy > Encyclopedia
+ function getAllParentCategories(&$stack)
+ {
+ global $wgUser,$wgLang;
+ $result = '';
+
+ # getting parents
+ $parents = $this->getParentCategories( );
+
+ if($parents == '')
+ {
+ # The current element has no more parent so we dump the stack
+ # and make a clean line of categories
+ $sk =& $wgUser->getSkin() ;
+
+ foreach ( array_reverse($stack) as $child => $parent )
+ {
+ # make a link of that parent
+ $result .= $sk->makeLink($wgLang->getNSText ( Namespace::getCategory() ).":".$parent,$parent);
+ $result .= ' &gt; ';
+ $lastchild = $child;
+ }
+ # append the last child.
+ # TODO : We should have a last child unless there is an error in the
+ # "categorylinks" table.
+ if(isset($lastchild)) { $result .= $lastchild; }
+
+ $result .= "<br/>\n";
+
+ # now we can empty the stack
+ $stack = array();
+
+ } else {
+ # look at parents of current category
+ foreach($parents as $parent)
+ {
+ # create a title object for the parent
+ $tpar = Title::newFromID($parent->cur_id);
+ # add it to the stack
+ $stack[$this->getText()] = $tpar->getText();
+ # grab its parents
+ $result .= $tpar->getAllParentCategories($stack);
+ }
+ }
+
+ if(isset($result)) { return $result; }
+ else { return ''; };
+ }
+
+
}
?>
diff --git a/includes/Tokenizer.php b/includes/Tokenizer.php
index ab18b106dbde..129d5e09313b 100644
--- a/includes/Tokenizer.php
+++ b/includes/Tokenizer.php
@@ -18,7 +18,7 @@ class Tokenizer {
# factory function
function newFromString( $s )
{
- $fname = "Tokenizer::newFromString";
+ $fname = 'Tokenizer::newFromString';
wfProfileIn( $fname );
$t = new Tokenizer();
@@ -37,7 +37,7 @@ class Tokenizer {
// the stored token.
function previewToken()
{
- $fname = "Tokenizer::previewToken";
+ $fname = 'Tokenizer::previewToken';
wfProfileIn( $fname );
if ( count( $this->mQueuedToken ) != 0 ) {
@@ -60,7 +60,7 @@ class Tokenizer {
// TODO: handling of French blanks not yet implemented
function nextToken()
{
- $fname = "Tokenizer::nextToken";
+ $fname = 'Tokenizer::nextToken';
wfProfileIn( $fname );
if ( count( $this->mQueuedToken ) != 0 ) {
@@ -71,48 +71,48 @@ class Tokenizer {
$token = false;
} else {
- $token["text"]="";
- $token["type"]="text";
+ $token['text']='';
+ $token['type']='text';
while ( $this->mPos <= $this->mTextLength ) {
switch ( @$ch = $this->mText[$this->mPos] ) {
case 'R': // for "RFC "
- if ( $this->continues("FC ") ) {
- $queueToken["type"] = $queueToken["text"] = "RFC ";
+ if ( $this->continues('FC ') ) {
+ $queueToken['type'] = $queueToken['text'] = 'RFC ';
$this->mQueuedToken[] = $queueToken;
$this->mPos += 3;
break 2; // switch + while
}
break;
case 'I': // for "ISBN "
- if ( $this->continues("SBN ") ) {
- $queueToken["type"] = $queueToken["text"] = "ISBN ";
+ if ( $this->continues('SBN ') ) {
+ $queueToken['type'] = $queueToken['text'] = 'ISBN ';
$this->mQueuedToken[] = $queueToken;
$this->mPos += 4;
break 2; // switch + while
}
break;
- case "[": // for links "[["
- if ( $this->continues("[[") ) {
- $queueToken["type"] = "[[[";
- $queueToken["text"] = "";
+ case '[': // for links "[["
+ if ( $this->continues('[[') ) {
+ $queueToken['type'] = '[[[';
+ $queueToken['text'] = '';
$this->mQueuedToken[] = $queueToken;
$this->mPos += 3;
break 2; // switch + while
- } else if ( $this->continues("[") ) {
- $queueToken["type"] = "[[";
- $queueToken["text"] = "";
+ } else if ( $this->continues('[') ) {
+ $queueToken['type'] = '[[';
+ $queueToken['text'] = '';
// Check for a "prefixed link", e.g. Al[[Khazar]]
// Mostly for arabic wikipedia
if ( $this->linkPrefixExtension ) {
while ( $this->linkPrefixExtension
- && ($len = strlen( $token["text"] ) ) > 0
- && !ctype_space( $token["text"][$len-1] ) )
+ && ($len = strlen( $token['text'] ) ) > 0
+ && !ctype_space( $token['text'][$len-1] ) )
{
//prepend the character to the link's open tag
- $queueToken["text"] = $token["text"][$len-1] . $queueToken["text"];
+ $queueToken['text'] = $token['text'][$len-1] . $queueToken['text'];
//remove character from the end of the text token
- $token["text"] = substr( $token["text"], 0, -1);
+ $token['text'] = substr( $token['text'], 0, -1);
}
}
$this->mQueuedToken[] = $queueToken;
@@ -120,10 +120,10 @@ class Tokenizer {
break 2; // switch + while
}
break;
- case "]": // for end of links "]]"
- if ( $this->continues("]") ) {
- $queueToken["type"] = "]]";
- $queueToken["text"] = "";
+ case ']': // for end of links "]]"
+ if ( $this->continues(']') ) {
+ $queueToken['type'] = ']]';
+ $queueToken['text'] = '';
$this->mQueuedToken[] = $queueToken;
$this->mPos += 2;
break 2; // switch + while
@@ -131,13 +131,13 @@ class Tokenizer {
break;
case "'": // for all kind of em's and strong's
if ( $this->continues("'") ) {
- $queueToken["type"] = "'";
- $queueToken["text"] = "";
+ $queueToken['type'] = "'";
+ $queueToken['text'] = '';
while( ($this->mPos+1 < $this->mTextLength)
&& $this->mText[$this->mPos+1] == "'" )
{
- $queueToken["type"] .= "'";
- $queueToken["pos"] = $this->mPos;
+ $queueToken['type'] .= "'";
+ $queueToken['pos'] = $this->mPos;
$this->mPos ++;
}
@@ -148,65 +148,65 @@ class Tokenizer {
break;
case "\n": // for block levels, actually, only "----" is handled.
case "\r": // headings are detected to close any unbalanced em or strong tags in a section
- if ( $this->continues( "----" ) )
+ if ( $this->continues( '----' ) )
{
- $queueToken["type"] = "----";
- $queueToken["text"] = "";
+ $queueToken['type'] = '----';
+ $queueToken['text'] = '';
$this->mQueuedToken[] = $queueToken;
$this->mPos += 5;
while ( $this->mPos<$this->mTextLength
- and $this->mText[$this->mPos] == "-" )
+ and $this->mText[$this->mPos] == '-' )
{
$this->mPos ++;
}
break 2;
} else if (
- $this->continues( "<h" ) and (
- $this->continues( "<h1" ) or
- $this->continues( "<h2" ) or
- $this->continues( "<h3" ) or
- $this->continues( "<h4" ) or
- $this->continues( "<h5" ) or
- $this->continues( "<h6" )
+ $this->continues( '<h' ) and (
+ $this->continues( '<h1' ) or
+ $this->continues( '<h2' ) or
+ $this->continues( '<h3' ) or
+ $this->continues( '<h4' ) or
+ $this->continues( '<h5' ) or
+ $this->continues( '<h6' )
)
) { // heading
- $queueToken["type"] = "h";
- $queueToken["text"] = "";
+ $queueToken['type'] = 'h';
+ $queueToken['text'] = '';
$this->mQueuedToken[] = $queueToken;
$this->mPos ++;
break 2; // switch + while
}
break;
- case "!": // French spacing rules have a space before exclamation
- case "?": // and question marks. Those have to become &nbsp;
- case ":": // And colons, Hashar says ...
- if ( $this->preceeded( " " ) )
+ case '!': // French spacing rules have a space before exclamation
+ case '?': // and question marks. Those have to become &nbsp;
+ case ':': // And colons, Hashar says ...
+ if ( $this->preceeded( ' ' ) )
{
// strip blank from Token
- $token["text"] = substr( $token["text"], 0, -1 );
- $queueToken["type"] = "blank";
- $queueToken["text"] = " {$ch}";
+ $token['text'] = substr( $token['text'], 0, -1 );
+ $queueToken['type'] = 'blank';
+ $queueToken['text'] = " {$ch}";
$this->mQueuedToken[] = $queueToken;
$this->mPos ++;
break 2; // switch + while
}
break;
- case "0": // A space between two numbers is used to ease reading
- case "1": // of big numbers, e.g. 1 000 000. Those spaces need
- case "2": // to be unbreakable
- case "3":
- case "4":
- case "5":
- case "6":
- case "7":
- case "8":
- case "9":
+ case '0': // A space between two numbers is used to ease reading
+ case '1': // of big numbers, e.g. 1 000 000. Those spaces need
+ case '2': // to be unbreakable
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
if ( ($this->mTextLength >= $this->mPos +2)
&& ($this->mText[$this->mPos+1] == " ")
&& ctype_digit( $this->mText[$this->mPos+2] ) )
{
- $queueToken["type"] = "blank";
- $queueToken["text"] = $ch . " ";
+ $queueToken['type'] = 'blank';
+ $queueToken['text'] = $ch . ' ';
$this->mQueuedToken[] = $queueToken;
$this->mPos += 2;
break 2; // switch + while
@@ -215,8 +215,8 @@ class Tokenizer {
case "\302": // first byte of UTF-8 Character Guillemet-left
if ( $this->continues( "\253 ") ) // second byte and a blank
{
- $queueToken["type"] = "blank";
- $queueToken["text"] = "\302\253 ";
+ $queueToken['type'] = 'blank';
+ $queueToken['text'] = "\302\253 ";
$this->mQueuedToken[] = $queueToken;
$this->mPos += 3;
break 2; // switch + while
@@ -225,20 +225,20 @@ class Tokenizer {
case "\273": //last byte of UTF-8 Character Guillemet-right
if ( $this->preceeded( " \302" ) )
{
- $queueToken["type"] = "blank";
- $queueToken["text"] = " \302\273";
- $token["text"] = substr( $token["text"], 0, -2 );
+ $queueToken['type'] = 'blank';
+ $queueToken['text'] = " \302\273";
+ $token['text'] = substr( $token['text'], 0, -2 );
$this->mQueuedToken[] = $queueToken;
$this->mPos ++;
break 2; // switch + while
}
break;
- case "&": //extensions like <timeline>, since HTML stripping has already been done,
+ case '&': //extensions like <timeline>, since HTML stripping has already been done,
//those look like &lt;timeline&gt;
if ( $this->continues( "lt;timeline&gt;" ) )
{
- $queueToken["type"] = "<timeline>";
- $queueToken["text"] = "&lt;timeline&gt;";
+ $queueToken['type'] = "<timeline>";
+ $queueToken['text'] = "&lt;timeline&gt;";
$this->mQueuedToken[] = $queueToken;
$this->mPos += 16;
break 2; // switch + while
@@ -246,7 +246,7 @@ class Tokenizer {
break;
} /* switch */
- $token["text"].=$ch;
+ $token['text'].=$ch;
$this->mPos ++;
// echo $this->mPos . "<br>\n";
} /* while */
@@ -286,11 +286,10 @@ class Tokenizer {
{
$n = strpos( $this->mText, $border, $this->mPos );
if ( $n === false )
- return "";
+ return '';
$ret = substr( $this->mText, $this->mPos, $n - $this->mPos );
$this->mPos = $n + strlen( $border ) + 1;
return $ret;
}
}
-
diff --git a/includes/User.php b/includes/User.php
index 111bebff1a78..2a06936a04aa 100644
--- a/includes/User.php
+++ b/includes/User.php
@@ -1,7 +1,7 @@
<?php
# See user.doc
-require_once( "WatchedItem.php" );
+require_once( 'WatchedItem.php' );
class User {
/* private */ var $mId, $mName, $mPassword, $mEmail, $mNewtalk;
@@ -13,15 +13,13 @@ class User {
/* private */ var $mCookiePassword;
/* private */ var $mRealName;
- function User()
- {
+ function User() {
$this->loadDefaults();
}
# Static factory method
#
- function newFromName( $name )
- {
+ function newFromName( $name ) {
$u = new User();
# Clean up name according to title rules
@@ -31,18 +29,15 @@ class User {
return $u;
}
- /* static */ function whoIs( $id )
- {
- return wfGetSQL( "user", "user_name", "user_id=$id" );
+ /* static */ function whoIs( $id ) {
+ return wfGetSQL( 'user', 'user_name', 'user_id='.$id );
}
- /* static */ function whoIsReal( $id )
- {
- return wfGetSQL( "user", "user_real_name", "user_id=$id" );
+ /* static */ function whoIsReal( $id ) {
+ return wfGetSQL( 'user', 'user_real_name', 'user_id='.$id );
}
- /* static */ function idFromName( $name )
- {
+ /* static */ function idFromName( $name ) {
$nt = Title::newFromText( $name );
if( is_null( $nt ) ) {
# Illegal name
@@ -50,7 +45,7 @@ class User {
}
$sql = "SELECT user_id FROM user WHERE user_name='" .
wfStrencode( $nt->getText() ) . "'";
- $res = wfQuery( $sql, DB_READ, "User::idFromName" );
+ $res = wfQuery( $sql, DB_READ, 'User::idFromName' );
if ( 0 == wfNumRows( $res ) ) {
return 0;
@@ -67,9 +62,8 @@ class User {
}
- /* static */ function randomPassword()
- {
- $pwchars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz";
+ /* static */ function randomPassword() {
+ $pwchars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz';
$l = strlen( $pwchars ) - 1;
wfSeedRandom();
@@ -80,33 +74,32 @@ class User {
return $np;
}
- function loadDefaults()
- {
+ function loadDefaults() {
global $wgLang, $wgIP;
global $wgNamespacesToBeSearchedDefault;
$this->mId = $this->mNewtalk = 0;
$this->mName = $wgIP;
- $this->mEmail = "";
- $this->mPassword = $this->mNewpassword = "";
+ $this->mEmail = '';
+ $this->mPassword = $this->mNewpassword = '';
$this->mRights = array();
$defOpt = $wgLang->getDefaultUserOptions() ;
foreach ( $defOpt as $oname => $val ) {
$this->mOptions[$oname] = $val;
}
foreach ($wgNamespacesToBeSearchedDefault as $nsnum => $val) {
- $this->mOptions["searchNs".$nsnum] = $val;
+ $this->mOptions['searchNs'.$nsnum] = $val;
}
unset( $this->mSkin );
$this->mDataLoaded = false;
$this->mBlockedby = -1; # Unset
$this->mTouched = '0'; # Allow any pages to be cached
- $this->cookiePassword = "";
+ $this->cookiePassword = '';
}
/* private */ function getBlockedStatus()
{
- global $wgIP, $wgBlockCache;
+ global $wgIP, $wgBlockCache, $wgProxyList;
if ( -1 != $this->mBlockedby ) { return; }
@@ -129,12 +122,20 @@ class User {
$this->mBlockreason = $block->mReason;
}
}
+
+ # Proxy blocking
+ if ( !$this->mBlockedby ) {
+ if ( array_key_exists( $wgIP, $wgProxyList ) ) {
+ $this->mBlockreason = wfMsg( 'proxyblockreason' );
+ $this->mBlockedby = "Proxy blocker";
+ }
+ }
}
function isBlocked()
{
$this->getBlockedStatus();
- if ( 0 == $this->mBlockedby ) { return false; }
+ if ( 0 === $this->mBlockedby ) { return false; }
return true;
}
@@ -151,10 +152,10 @@ class User {
function SetupSession() {
global $wgSessionsInMemcached, $wgCookiePath, $wgCookieDomain;
if( $wgSessionsInMemcached ) {
- require_once( "MemcachedSessions.php" );
+ require_once( 'MemcachedSessions.php' );
}
session_set_cookie_params( 0, $wgCookiePath, $wgCookieDomain );
- session_cache_limiter( "private, must-revalidate" );
+ session_cache_limiter( 'private, must-revalidate' );
@session_start();
}
@@ -290,14 +291,12 @@ class User {
return $this->mName;
}
- function setName( $str )
- {
+ function setName( $str ) {
$this->loadFromDatabase();
$this->mName = $str;
}
- function getNewtalk()
- {
+ function getNewtalk() {
$this->loadFromDatabase();
return ( 0 != $this->mNewtalk );
}
@@ -321,20 +320,17 @@ class User {
return ($timestamp >= $this->mTouched);
}
- function getPassword()
- {
+ function getPassword() {
$this->loadFromDatabase();
return $this->mPassword;
}
- function getNewpassword()
- {
+ function getNewpassword() {
$this->loadFromDatabase();
return $this->mNewpassword;
}
- function addSalt( $p )
- {
+ function addSalt( $p ) {
global $wgPasswordSalt;
if($wgPasswordSalt)
return md5( "{$this->mId}-{$p}" );
@@ -342,67 +338,57 @@ class User {
return $p;
}
- function encryptPassword( $p )
- {
+ function encryptPassword( $p ) {
return $this->addSalt( md5( $p ) );
}
- function setPassword( $str )
- {
+ function setPassword( $str ) {
$this->loadFromDatabase();
$this->setCookiePassword( $str );
$this->mPassword = $this->encryptPassword( $str );
- $this->mNewpassword = "";
+ $this->mNewpassword = '';
}
- function setCookiePassword( $str )
- {
+ function setCookiePassword( $str ) {
$this->loadFromDatabase();
$this->mCookiePassword = md5( $str );
}
- function setNewpassword( $str )
- {
+ function setNewpassword( $str ) {
$this->loadFromDatabase();
$this->mNewpassword = $this->encryptPassword( $str );
}
- function getEmail()
- {
+ function getEmail() {
$this->loadFromDatabase();
return $this->mEmail;
}
- function setEmail( $str )
- {
+ function setEmail( $str ) {
$this->loadFromDatabase();
$this->mEmail = $str;
}
- function getRealName()
- {
+ function getRealName() {
$this->loadFromDatabase();
return $this->mRealName;
}
- function setRealName( $str )
- {
+ function setRealName( $str ) {
$this->loadFromDatabase();
$this->mRealName = $str;
}
- function getOption( $oname )
- {
+ function getOption( $oname ) {
$this->loadFromDatabase();
if ( array_key_exists( $oname, $this->mOptions ) ) {
return $this->mOptions[$oname];
} else {
- return "";
+ return '';
}
}
- function setOption( $oname, $val )
- {
+ function setOption( $oname, $val ) {
$this->loadFromDatabase();
if ( $oname == 'skin' ) {
# Clear cached skin, so the new one displays immediately in Special:Preferences
@@ -412,73 +398,93 @@ class User {
$this->invalidateCache();
}
- function getRights()
- {
+ function getRights() {
$this->loadFromDatabase();
return $this->mRights;
}
- function addRight( $rname )
- {
+ function addRight( $rname ) {
$this->loadFromDatabase();
array_push( $this->mRights, $rname );
$this->invalidateCache();
}
- function isSysop()
- {
+ function isSysop() {
$this->loadFromDatabase();
if ( 0 == $this->mId ) { return false; }
- return in_array( "sysop", $this->mRights );
+ return in_array( 'sysop', $this->mRights );
}
- function isDeveloper()
- {
+ function isDeveloper() {
$this->loadFromDatabase();
if ( 0 == $this->mId ) { return false; }
- return in_array( "developer", $this->mRights );
+ return in_array( 'developer', $this->mRights );
}
- function isBureaucrat()
- {
+ function isBureaucrat() {
$this->loadFromDatabase();
if ( 0 == $this->mId ) { return false; }
- return in_array( "bureaucrat", $this->mRights );
+ return in_array( 'bureaucrat', $this->mRights );
}
- function isBot()
- {
+ function isBot() {
$this->loadFromDatabase();
# Why was this here? I need a UID=0 conversion script [TS]
# if ( 0 == $this->mId ) { return false; }
- return in_array( "bot", $this->mRights );
+ return in_array( 'bot', $this->mRights );
}
- function &getSkin()
- {
+ function &getSkin() {
if ( ! isset( $this->mSkin ) ) {
+ # get all skin names available from SkinNames.php
$skinNames = Skin::getSkinNames();
- $s = $this->getOption( "skin" );
- if ( "" == $s ) { $s = 'standard'; }
-
- if ( !isset( $skinNames[$s] ) ) {
+ # get the user skin
+ $userSkin = $this->getOption( 'skin' );
+ if ( $userSkin == '' ) { $userSkin = 'standard'; }
+
+ if ( !isset( $skinNames[$userSkin] ) ) {
+ # in case the user skin could not be found find a replacement
$fallback = array(
- 'standard' => "Standard",
- 'nostalgia' => "Nostalgia",
- 'cologneblue' => "Cologne Blue");
- if(is_int($s) && isset( $fallback[$s]) ){
- $sn = $fallback[$s];
+ 0 => 'SkinStandard',
+ 1 => 'SkinNostalgia',
+ 2 => 'SkinCologneBlue');
+ # if phptal is enabled we should have monobook skin that superseed
+ # the good old SkinStandard.
+ if ( isset( $skinNames['monobook'] ) ) {
+ $fallback[0] = 'SkinMonoBook';
+ }
+
+ if(is_numeric($userSkin) && isset( $fallback[$userSkin]) ){
+ $sn = $fallback[$userSkin];
} else {
- $sn = "SkinStandard";
+ $sn = 'SkinStandard';
}
} else {
- $sn = "Skin" . $skinNames[$s];
+ # The user skin is available
+ $sn = 'Skin' . $skinNames[$userSkin];
+ }
+
+ # only require the needed stuff
+ switch($sn) {
+ case 'SkinMonoBook':
+ require_once( 'SkinPHPTal.php' );
+ break;
+ case 'SkinStandard':
+ require_once( 'SkinStandard.php' );
+ break;
+ case 'SkinNostalgia':
+ require_once( 'SkinNostalgia.php' );
+ break;
+ case 'SkinCologneBlue':
+ require_once( 'SkinCologneBlue.php' );
+ break;
}
+ # now we can create the skin object
$this->mSkin = new $sn;
}
return $this->mSkin;
@@ -502,18 +508,16 @@ class User {
}
- /* private */ function encodeOptions()
- {
+ /* private */ function encodeOptions() {
$a = array();
foreach ( $this->mOptions as $oname => $oval ) {
- array_push( $a, "{$oname}={$oval}" );
+ array_push( $a, $oname.'='.$oval );
}
$s = implode( "\n", $a );
return wfStrencode( $s );
}
- /* private */ function decodeOptions( $str )
- {
+ /* private */ function decodeOptions( $str ) {
$a = explode( "\n", $str );
foreach ( $a as $s ) {
if ( preg_match( "/^(.[^=]*)=(.*)$/", $s, $m ) ) {
@@ -522,40 +526,37 @@ class User {
}
}
- function setCookies()
- {
+ function setCookies() {
global $wgCookieExpiration, $wgCookiePath, $wgCookieDomain, $wgDBname;
if ( 0 == $this->mId ) return;
$this->loadFromDatabase();
$exp = time() + $wgCookieExpiration;
$_SESSION['wsUserID'] = $this->mId;
- setcookie( "{$wgDBname}UserID", $this->mId, $exp, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgDBname.'UserID', $this->mId, $exp, $wgCookiePath, $wgCookieDomain );
$_SESSION['wsUserName'] = $this->mName;
- setcookie( "{$wgDBname}UserName", $this->mName, $exp, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgDBname.'UserName', $this->mName, $exp, $wgCookiePath, $wgCookieDomain );
$_SESSION['wsUserPassword'] = $this->mPassword;
- if ( 1 == $this->getOption( "rememberpassword" ) ) {
- setcookie( "{$wgDBname}Password", $this->mCookiePassword, $exp, $wgCookiePath, $wgCookieDomain );
+ if ( 1 == $this->getOption( 'rememberpassword' ) ) {
+ setcookie( $wgDBname.'Password', $this->mCookiePassword, $exp, $wgCookiePath, $wgCookieDomain );
} else {
- setcookie( "{$wgDBname}Password", "", time() - 3600 );
+ setcookie( $wgDBname.'Password', '', time() - 3600 );
}
}
- function logout()
- {
+ function logout() {
global $wgCookiePath, $wgCookieDomain, $wgDBname;
$this->mId = 0;
$_SESSION['wsUserID'] = 0;
- setcookie( "{$wgDBname}UserID", "", time() - 3600, $wgCookiePath, $wgCookieDomain );
- setcookie( "{$wgDBname}Password", "", time() - 3600, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgDBname.'UserID', '', time() - 3600, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgDBname.'Password', '', time() - 3600, $wgCookiePath, $wgCookieDomain );
}
- function saveSettings()
- {
+ function saveSettings() {
global $wgMemc, $wgDBname;
if ( ! $this->mNewtalk ) {
@@ -586,11 +587,10 @@ class User {
# Checks if a user with the given name exists
#
- function idForName()
- {
+ function idForName() {
$gotid = 0;
$s = trim( $this->mName );
- if ( 0 == strcmp( "", $s ) ) return 0;
+ if ( 0 == strcmp( '', $s ) ) return 0;
$sql = "SELECT user_id FROM user WHERE user_name='" .
wfStrencode( $s ) . "'";
@@ -598,15 +598,14 @@ class User {
if ( 0 == wfNumRows( $res ) ) { return 0; }
$s = wfFetchObject( $res );
- if ( "" == $s ) return 0;
+ if ( '' == $s ) return 0;
$gotid = $s->user_id;
wfFreeResult( $res );
return $gotid;
}
- function addToDatabase()
- {
+ function addToDatabase() {
$sql = "INSERT INTO user (user_name,user_password,user_newpassword," .
"user_email, user_real_name, user_rights, user_options) " .
" VALUES ('" . wfStrencode( $this->mName ) . "', '" .
@@ -614,7 +613,7 @@ class User {
wfStrencode( $this->mNewpassword ) . "', '" .
wfStrencode( $this->mEmail ) . "', '" .
wfStrencode( $this->mRealName ) . "', '" .
- wfStrencode( implode( ",", $this->mRights ) ) . "', '" .
+ wfStrencode( implode( ',', $this->mRights ) ) . "', '" .
$this->encodeOptions() . "')";
wfQuery( $sql, DB_WRITE, "User::addToDatabase" );
$this->mId = $this->idForName();
@@ -625,14 +624,14 @@ class User {
global $wgIP;
# If the (non-anonymous) user is blocked, this function will block any IP address
# that they successfully log on from.
- $fname = "User::spreadBlock";
+ $fname = 'User::spreadBlock';
wfDebug( "User:spreadBlock()\n" );
if ( $this->mId == 0 ) {
return;
}
- $userblock = Block::newFromDB( "", $this->mId );
+ $userblock = Block::newFromDB( '', $this->mId );
if ( !$userblock->isValid() ) {
return;
}
@@ -646,11 +645,11 @@ class User {
}
# Make a new block object with the desired properties
- wfDebug( "Autoblocking {$this->mUserName}@{$wgIP}\n" );
+ wfDebug( "Autoblocking {$this->mName}@{$wgIP}\n" );
$ipblock->mAddress = $wgIP;
$ipblock->mUser = 0;
$ipblock->mBy = $userblock->mBy;
- $ipblock->mReason = wfMsg( "autoblocker", $this->getName(), $userblock->mReason );
+ $ipblock->mReason = wfMsg( 'autoblocker', $this->getName(), $userblock->mReason );
$ipblock->mTimestamp = wfTimestampNow();
$ipblock->mAuto = 1;
# If the user is already blocked with an expiry date, we don't
@@ -675,17 +674,17 @@ class User {
// stubthreshold is only included below for completeness,
// it will always be 0 when this function is called by parsercache.
- $confstr = $this->getOption( "quickbar" );
- $confstr .= "!" . $this->getOption( "underline" );
- $confstr .= "!" . $this->getOption( "hover" );
- $confstr .= "!" . $this->getOption( "skin" );
- $confstr .= "!" . $this->getOption( "math" );
- $confstr .= "!" . $this->getOption( "highlightbroken" );
- $confstr .= "!" . $this->getOption( "stubthreshold" );
- $confstr .= "!" . $this->getOption( "editsection" );
- $confstr .= "!" . $this->getOption( "editsectiononrightclick" );
- $confstr .= "!" . $this->getOption( "showtoc" );
- $confstr .= "!" . $this->getOption( "date" );
+ $confstr = $this->getOption( 'quickbar' );
+ $confstr .= '!' . $this->getOption( 'underline' );
+ $confstr .= '!' . $this->getOption( 'hover' );
+ $confstr .= '!' . $this->getOption( 'skin' );
+ $confstr .= '!' . $this->getOption( 'math' );
+ $confstr .= '!' . $this->getOption( 'highlightbroken' );
+ $confstr .= '!' . $this->getOption( 'stubthreshold' );
+ $confstr .= '!' . $this->getOption( 'editsection' );
+ $confstr .= '!' . $this->getOption( 'editsectiononrightclick' );
+ $confstr .= '!' . $this->getOption( 'showtoc' );
+ $confstr .= '!' . $this->getOption( 'date' );
if(strlen($confstr) > 32)
$hash = md5($confstr);
@@ -694,14 +693,13 @@ class User {
return $hash;
}
- function isAllowedToCreateAccount()
- {
+ function isAllowedToCreateAccount() {
global $wgWhitelistAccount;
$allowed = false;
if (!$wgWhitelistAccount) { return 1; }; // default behaviour
foreach ($wgWhitelistAccount as $right => $ok) {
- $userHasRight = (!strcmp($right, "user") || in_array($right, $this->getRights()));
+ $userHasRight = (!strcmp($right, 'user') || in_array($right, $this->getRights()));
$allowed |= ($ok && $userHasRight);
}
return $allowed;
@@ -717,6 +715,15 @@ class User {
function getUserPage() {
return Title::makeTitle( NS_USER, $this->mName );
}
+
+ /* static */ function getMaxID() {
+ $row = wfGetArray( 'user', array('max(user_id) as m'), false );
+ return $row->m;
+ }
+
+ function isNewbie() {
+ return $this->mId > User::getMaxID() * 0.99 && !$this->isSysop() || $this->getID() == 0;
+ }
}
?>
diff --git a/includes/UserTalkUpdate.php b/includes/UserTalkUpdate.php
index 306cd3c80d81..66ea7a9aee25 100644
--- a/includes/UserTalkUpdate.php
+++ b/includes/UserTalkUpdate.php
@@ -33,6 +33,7 @@ class UserTalkUpdate {
} else {
# Not ours. If writing, mark it as modified.
+ $sql = false;
if ( 1 == $this->mAction ) {
$user = new User();
$user->setID(User::idFromName($this->mTitle));
diff --git a/includes/ViewCountUpdate.php b/includes/ViewCountUpdate.php
index 84a03991f8ce..16976f11b0f2 100644
--- a/includes/ViewCountUpdate.php
+++ b/includes/ViewCountUpdate.php
@@ -1,6 +1,6 @@
<?php
+# $Id$
# See deferred.doc
-
class ViewCountUpdate {
var $mPageID;
@@ -12,13 +12,12 @@ class ViewCountUpdate {
function doUpdate()
{
- global $wgDisableCounters;
+ global $wgDisableCounters, $wgIsMySQL;
if ( $wgDisableCounters ) { return; }
-
- $sql = "UPDATE LOW_PRIORITY cur SET cur_counter=(1+cur_counter)," .
+ $lowpri=$wgIsMySQL?"LOW_PRIORITY":"";
+ $sql = "UPDATE $lowpri cur SET cur_counter=(1+cur_counter)," .
"cur_timestamp=cur_timestamp WHERE cur_id={$this->mPageID}";
$res = wfQuery( $sql, DB_WRITE, "ViewCountUpdate::doUpdate" );
}
}
-
?>
diff --git a/includes/WatchedItem.php b/includes/WatchedItem.php
index 74371be4bf25..23ad2804e1de 100644
--- a/includes/WatchedItem.php
+++ b/includes/WatchedItem.php
@@ -36,10 +36,22 @@ class WatchedItem {
function addWatch()
{
+ global $wgIsMySQL;
# REPLACE instead of INSERT because occasionally someone
# accidentally reloads a watch-add operation.
- $sql = "REPLACE INTO watchlist (wl_user, wl_namespace,wl_title) VALUES ($this->id,$this->ns,'$this->eti')";
- $res = wfQuery( $sql, DB_WRITE );
+ if ($wgIsMySQL) {
+ $sql = "REPLACE INTO watchlist (wl_user, wl_namespace,wl_title) ".
+ "VALUES ($this->id,$this->ns,'$this->eti')";
+ $res = wfQuery( $sql, DB_WRITE );
+ } else {
+ $sql = "DELETE FROM watchlist WHERE wl_user=$this->id AND
+ wl_namespace=$this->ns AND wl_title='$this->eti'";
+ wfQuery( $sql, DB_WRITE);
+ $sql = "INSERT INTO watchlist (wl_user, wl_namespace,wl_title) ".
+ "VALUES ($this->id,$this->ns,'$this->eti')";
+ $res = wfQuery( $sql, DB_WRITE );
+ }
+
if( $res === false ) return false;
global $wgMemc;
@@ -49,7 +61,7 @@ class WatchedItem {
function removeWatch()
{
- $sql = "DELETE FROM watchlist WHERE wl_user=$this->id AND wl_namespace=$this->ns AND wl_title='$this->eti' LIMIT 1";
+ $sql = "DELETE FROM watchlist WHERE wl_user=$this->id AND wl_namespace=$this->ns AND wl_title='$this->eti'";
$res = wfQuery( $sql, DB_WRITE );
if( $res === false ) return false;
diff --git a/includes/memcached-client.php b/includes/memcached-client.php
index 3f0eb44f9e0f..17d9ecbecd3d 100644
--- a/includes/memcached-client.php
+++ b/includes/memcached-client.php
@@ -667,7 +667,7 @@ class memcached
function _dead_sock ($sock)
{
$host = array_search($sock, $this->_cache_sock);
- list ($ip, $port) = explode(":", $host);
+ @list ($ip, $port) = explode(":", $host);
$this->_host_dead[$ip] = time() + 30 + intval(rand(0, 10));
$this->_host_dead[$host] = $this->_host_dead[$ip];
unset($this->_cache_sock[$host]);
@@ -737,13 +737,7 @@ class memcached
*/
function _hashfunc ($key)
{
- $hash = 0;
- for ($i=0; $i<strlen($key); $i++)
- {
- $hash = $hash*33 + ord($key[$i]);
- }
-
- return $hash;
+ return crc32($key);
}
// }}}