var $mDTopen, $mLastSection; # Used for processing DL, PRE
var $mLanguageLinks, $mSupressQuickbar;
+ var $mOnloadHandler;
+ var $mDoNothing;
function OutputPage()
{
$this->mKeywords = $this->mLinktags = array();
$this->mHTMLtitle = $this->mPagetitle = $this->mBodytext =
$this->mLastSection = $this->mRedirect = $this->mLastModified =
- $this->mSubtitle = $this->mDebugtext = $this->mRobotpolicy = "";
+ $this->mSubtitle = $this->mDebugtext = $this->mRobotpolicy =
+ $this->mOnloadHandler = "";
$this->mIsarticle = $this->mPrintable = true;
$this->mSupressQuickbar = $this->mDTopen = $this->mPrintable = false;
$this->mLanguageLinks = array();
$this->mCategoryLinks = array() ;
$this->mAutonumber = 0;
+ $this->mDoNothing = false;
}
function addHeader( $name, $val ) { array_push( $this->mHeaders, "$name: $val" ) ; }
function addKeyword( $text ) { array_push( $this->mKeywords, $text ); }
function addLink( $rel, $rev, $target ) { array_push( $this->mLinktags, array( $rel, $rev, $target ) ); }
+ # checkLastModified tells the client to use the client-cached page if
+ # possible. If sucessful, the OutputPage is disabled so that
+ # any future call to OutputPage->output() have no effect. The method
+ # returns true iff cache-ok headers was sent.
function checkLastModified ( $timestamp )
{
global $wgLang, $wgCachePages, $wgUser;
$lastmod = gmdate( "D, j M Y H:i:s", wfTimestamp2Unix(
max( $timestamp, $wgUser->mTouched ) ) ) . " GMT";
- if( $_SERVER["HTTP_IF_MODIFIED_SINCE"] != "" ) {
- # IE sends sizes after the date for compressed pages:
+ if( !empty( $_SERVER["HTTP_IF_MODIFIED_SINCE"] ) ) {
+ # IE sends sizes after the date like this:
# Wed, 20 Aug 2003 06:51:19 GMT; length=5202
# this breaks strtotime().
$modsince = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
header( "Cache-Control: private, must-revalidate, max-age=0" );
header( "Last-Modified: {$lastmod}" );
wfDebug( "CACHED client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp\n", false );
- exit;
+ $this->disable();
+ return true;
} else {
wfDebug( "READY client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp\n", false );
$this->mLastModified = $lastmod;
function isArticle() { return $this->mIsarticle; }
function setPrintable() { $this->mPrintable = true; }
function isPrintable() { return $this->mPrintable; }
+ function setOnloadHandler( $js ) { $this->mOnloadHandler = $js; }
+ function getOnloadHandler() { return $this->mOnloadHandler; }
+ function disable() { $this->mDoNothing = true; }
function getLanguageLinks() {
- global $wgUseNewInterlanguage, $wgTitle, $wgLanguageCode;
- global $wgDBconnection, $wgDBname, $wgDBintlname;
-
- if ( ! $wgUseNewInterlanguage )
- return $this->mLanguageLinks;
-
- mysql_select_db( $wgDBintlname, $wgDBconnection ) or die(
- htmlspecialchars(mysql_error()) );
-
- $list = array();
- $sql = "SELECT * FROM ilinks WHERE lang_from=\"" .
- "{$wgLanguageCode}\" AND title_from=\"" . $wgTitle->getDBkey() . "\"";
- $res = mysql_query( $sql, $wgDBconnection );
-
- while ( $q = mysql_fetch_object ( $res ) ) {
- $list[] = $q->lang_to . ":" . $q->title_to;
- }
- mysql_free_result( $res );
- mysql_select_db( $wgDBname, $wgDBconnection ) or die(
- htmlspecialchars(mysql_error()) );
-
- return $list;
+ global $wgTitle, $wgLanguageCode;
+ global $wgDBconnection, $wgDBname;
+ return $this->mLanguageLinks;
}
-
function supressQuickbar() { $this->mSupressQuickbar = true; }
function isQuickbarSupressed() { return $this->mSupressQuickbar; }
function addWikiText( $text, $linestart = true )
{
global $wgUseTeX;
- wfProfileIn( "OutputPage::addWikiText" );
+ $fname = "OutputPage::addWikiText";
+ wfProfileIn( $fname );
$unique = "3iyZiyA7iMwg5rhxP0Dcc9oTnj8qD1jm1Sfv4";
$unique2 = "4LIQ9nXtiYFPCSfitVwDw7EYwQlL4GeeQ7qSO";
$unique3 = "fPaA8gDfdLBqzj68Yjg9Hil3qEF8JGO0uszIp";
$q = preg_split( "/<\\/\\s*nowiki\\s*>/i", $p[1], 2 );
++$nwsecs;
$nwlist[$nwsecs] = wfEscapeHTMLTagsOnly($q[0]);
- $stripped .= $unique;
+ $stripped .= $unique . $nwsecs . "s";
$text = $q[1];
}
}
$q = preg_split( "/<\\/\\s*math\\s*>/i", $p[1], 2 );
++$mathsecs;
$mathlist[$mathsecs] = renderMath($q[0]);
- $stripped2 .= $unique2;
+ $stripped2 .= $unique2 . $mathsecs . "s";
$stripped = $q[1];
}
}
$q = preg_split( "/<\\/\\s*pre\\s*>/i", $p[1], 2 );
++$presecs;
$prelist[$presecs] = "<pre>". wfEscapeHTMLTagsOnly($q[0]). "</pre>";
- $stripped3 .= $unique3;
+ $stripped3 .= $unique3 . $presecs . "s";
$stripped2 = $q[1];
}
}
$specialChars = array("\\", "$");
$escapedChars = array("\\\\", "\\$");
for ( $i = 1; $i <= $presecs; ++$i ) {
- $text = preg_replace( "/{$unique3}/", str_replace( $specialChars,
- $escapedChars, $prelist[$i] ), $text, 1 );
+ $text = preg_replace( "/{$unique3}{$i}s/", str_replace( $specialChars,
+ $escapedChars, $prelist[$i] ), $text );
}
for ( $i = 1; $i <= $mathsecs; ++$i ) {
- $text = preg_replace( "/{$unique2}/", str_replace( $specialChars,
- $escapedChars, $mathlist[$i] ), $text, 1 );
+ $text = preg_replace( "/{$unique2}{$i}s/", str_replace( $specialChars,
+ $escapedChars, $mathlist[$i] ), $text );
}
for ( $i = 1; $i <= $nwsecs; ++$i ) {
- $text = preg_replace( "/{$unique}/", str_replace( $specialChars,
- $escapedChars, $nwlist[$i] ), $text, 1 );
+ $text = preg_replace( "/{$unique}{$i}s/", str_replace( $specialChars,
+ $escapedChars, $nwlist[$i] ), $text );
}
$this->addHTML( $text );
- wfProfileOut();
+ wfProfileOut( $fname );
}
function sendCacheControl() {
{
global $wgUser, $wgLang, $wgDebugComments, $wgCookieExpiration;
global $wgInputEncoding, $wgOutputEncoding, $wgLanguageCode;
- wfProfileIn( "OutputPage::output" );
+ if( $this->mDoNothing ){
+ return;
+ }
+ $fname = "OutputPage::output";
+ wfProfileIn( $fname );
+
$sk = $wgUser->getSkin();
- wfProfileIn( "OutputPage::output-headers" );
$this->sendCacheControl();
header( "Content-type: text/html; charset={$wgOutputEncoding}" );
header( "Content-language: {$wgLanguageCode}" );
if ( "" != $this->mRedirect ) {
+ if( substr( $this->mRedirect, 0, 4 ) != "http" ) {
+ # Standards require redirect URLs to be absolute
+ global $wgServer;
+ $this->mRedirect = $wgServer . $this->mRedirect;
+ }
header( "Location: {$this->mRedirect}" );
- wfProfileOut();
return;
}
foreach( $this->mCookies as $name => $val ) {
setcookie( $name, $val, $exp, "/" );
}
- wfProfileOut();
-
- wfProfileIn( "OutputPage::output-middle" );
- $sk->initPage();
- $this->out( $this->headElement() );
-
- $this->out( "\n<body" );
- $ops = $sk->getBodyOptions();
- foreach ( $ops as $name => $val ) {
- $this->out( " $name='$val'" );
- }
- $this->out( ">\n" );
- if ( $wgDebugComments ) {
- $this->out( "<!-- Wiki debugging output:\n" .
- $this->mDebugtext . "-->\n" );
- }
- $this->out( $sk->beforeContent() );
- wfProfileOut();
-
- wfProfileIn( "OutputPage::output-bodytext" );
- $this->out( $this->mBodytext );
- wfProfileOut();
- wfProfileIn( "OutputPage::output-after" );
- $this->out( $sk->afterContent() );
- wfProfileOut();
- wfProfileOut(); # A hack - we can't report after here
- $this->out( $this->reportTime() );
-
- $this->out( "\n</body></html>" );
+ $sk->outputPage( $this );
flush();
}
function setEncodings()
{
- global $HTTP_SERVER_VARS, $wgInputEncoding, $wgOutputEncoding;
+ global $wgInputEncoding, $wgOutputEncoding;
global $wgUser, $wgLang;
$wgInputEncoding = strtolower( $wgInputEncoding );
- $s = $HTTP_SERVER_VARS['HTTP_ACCEPT_CHARSET'];
if( $wgUser->getOption( 'altencoding' ) ) {
$wgLang->setAltEncoding();
return;
}
- if ( "" == $s ) {
+ if ( empty( $_SERVER['HTTP_ACCEPT_CHARSET'] ) ) {
$wgOutputEncoding = strtolower( $wgOutputEncoding );
return;
}
- $a = explode( ",", $s );
+
+ /*
+ # This code is unused anyway!
+ # Commenting out. --bv 2003-11-15
+
+ $a = explode( ",", $_SERVER['HTTP_ACCEPT_CHARSET'] );
$best = 0.0;
$bestset = "*";
# Disable for now
#
+ */
$wgOutputEncoding = $wgInputEncoding;
}
+ # Returns a HTML comment with the elapsed time since request.
+ # This method has no side effects.
function reportTime()
{
- global $wgRequestTime, $wgDebugLogFile, $HTTP_SERVER_VARS;
- global $wgProfiling, $wgProfileStack, $wgUser;
+ global $wgRequestTime;
list( $usec, $sec ) = explode( " ", microtime() );
$now = (float)$sec + (float)$usec;
list( $usec, $sec ) = explode( " ", $wgRequestTime );
$start = (float)$sec + (float)$usec;
$elapsed = $now - $start;
-
- if ( "" != $wgDebugLogFile ) {
- $prof = "";
- if( $wgProfiling and count( $wgProfileStack ) ) {
- $lasttime = $start;
- foreach( $wgProfileStack as $ile ) {
- # "foo::bar 99 0.12345 1 0.23456 2"
- if( preg_match( '/^(\S+)\s+([0-9]+)\s+([0-9\.]+)\s+([0-9\.]+)\s+([0-9\.]+)\s+([0-9\.]+)/', $ile, $m ) ) {
- $thisstart = (float)$m[3] + (float)$m[4] - $start;
- $thisend = (float)$m[5] + (float)$m[6] - $start;
- $thiselapsed = $thisend - $thisstart;
- $thispercent = $thiselapsed / $elapsed * 100.0;
-
- $prof .= sprintf( "\tat %04.3f in %04.3f (%2.1f%%) - %s %s\n",
- $thisstart, $thiselapsed, $thispercent,
- str_repeat( "*", $m[2] ), $m[1] );
- $lasttime = $thistime;
- #$prof .= "\t(^ $ile)\n";
- } else {
- $prof .= "\t?broken? $ile\n";
- }
- }
- }
-
- if( $forward = $HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR'] )
- $forward = " forwarded for $forward";
- if( $client = $HTTP_SERVER_VARS['HTTP_CLIENT_IP'] )
- $forward .= " client IP $client";
- if( $from = $HTTP_SERVER_VARS['HTTP_FROM'] )
- $forward .= " from $from";
- if( $forward )
- $forward = "\t(proxied via {$HTTP_SERVER_VARS['REMOTE_ADDR']}{$forward})";
- if($wgUser->getId() == 0)
- $forward .= " anon";
- $log = sprintf( "%s\t%04.3f\t%s\n",
- gmdate( "YmdHis" ), $elapsed,
- urldecode( $HTTP_SERVER_VARS['REQUEST_URI'] . $forward ) );
- error_log( $log . $prof, 3, $wgDebugLogFile );
- }
$com = sprintf( "<!-- Time since request: %01.2f secs. -->",
$elapsed );
return $com;
$this->returnToMain( false );
$this->output();
- exit;
+ wfAbruptExit();
}
function sysopRequired()
$sk = $wgUser->getSkin();
$ap = $sk->makeKnownLink( wfMsg( "administrators" ), "" );
- $text = str_replace( "$1", $ap, wfMsg( "sysoptext" ) );
- $this->addHTML( $text );
+ $this->addHTML( wfMsg( "sysoptext", $ap ) );
$this->returnToMain();
}
$sk = $wgUser->getSkin();
$ap = $sk->makeKnownLink( wfMsg( "administrators" ), "" );
- $text = str_replace( "$1", $ap, wfMsg( "developertext" ) );
- $this->addHTML( $text );
+ $this->addHTML( wfMsg( "developertext", $ap ) );
$this->returnToMain();
}
function databaseError( $fname )
{
global $wgUser, $wgCommandLineMode;
-
- $this->setPageTitle( wfMsg( "databaseerror" ) );
+
+ $this->setPageTitle( wfMsgNoDB( "databaseerror" ) );
$this->setRobotpolicy( "noindex,nofollow" );
$this->setArticleFlag( false );
if ( $wgCommandLineMode ) {
- $msg = wfMsg( "dberrortextcl" );
+ $msg = wfMsgNoDB( "dberrortextcl" );
} else {
- $msg = wfMsg( "dberrortextcl" );
+ $msg = wfMsgNoDB( "dberrortext" );
}
+
$msg = str_replace( "$1", htmlspecialchars( wfLastDBquery() ), $msg );
$msg = str_replace( "$2", htmlspecialchars( $fname ), $msg );
$msg = str_replace( "$3", wfLastErrno(), $msg );
$msg = str_replace( "$4", htmlspecialchars( wfLastError() ), $msg );
-
+
if ( $wgCommandLineMode ) {
- print $msg;
- exit();
+ print "$msg\n";
+ wfAbruptExit();
}
$sk = $wgUser->getSkin();
- $shlink = $sk->makeKnownLink( wfMsg( "searchhelppage" ),
- wfMsg( "searchingwikipedia" ) );
+ $shlink = $sk->makeKnownLink( wfMsgNoDB( "searchhelppage" ),
+ wfMsgNoDB( "searchingwikipedia" ) );
$msg = str_replace( "$5", $shlink, $msg );
$this->mBodytext = $msg;
$this->output();
- exit();
+ wfAbruptExit();
}
- function readOnlyPage( $source = "" )
+ function readOnlyPage( $source = "", $protected = false )
{
global $wgUser, $wgReadOnlyFile;
- $this->setPageTitle( wfMsg( "readonly" ) );
$this->setRobotpolicy( "noindex,nofollow" );
$this->setArticleFlag( false );
- $reason = implode( "", file( $wgReadOnlyFile ) );
- $text = str_replace( "$1", $reason, wfMsg( "readonlytext" ) );
+ if( $protected ) {
+ $this->setPageTitle( wfMsg( "viewsource" ) );
+ $this->addWikiText( wfMsg( "protectedtext" ) );
+ } else {
+ $this->setPageTitle( wfMsg( "readonly" ) );
+ $reason = file_get_contents( $wgReadOnlyFile );
+ $this->addHTML( wfMsg( "readonlytext", $reason ) );
+ }
if($source) {
$rows = $wgUser->getOption( "rows" );
$cols = $wgUser->getOption( "cols" );
$text .= "</p>\n<textarea cols='$cols' rows='$rows' readonly>" .
htmlspecialchars( $source ) . "\n</textarea>";
+ $this->addHTML( $text );
}
- $this->addHTML( $text );
$this->returnToMain( false );
}
$this->mBodytext = $message;
$this->output();
- exit;
+ wfAbruptExit();
}
function unexpectedValueError( $name, $val )
{
- $msg = str_replace( "$1", $name, wfMsg( "unexpected" ) );
- $msg = str_replace( "$2", $val, $msg );
- $this->fatalError( $msg );
+ $this->fatalError( wfMsg( "unexpected", $name, $val ) );
}
function fileCopyError( $old, $new )
{
- $msg = str_replace( "$1", $old, wfMsg( "filecopyerror" ) );
- $msg = str_replace( "$2", $new, $msg );
- $this->fatalError( $msg );
+ $this->fatalError( wfMsg( "filecopyerror", $old, $new ) );
}
function fileRenameError( $old, $new )
{
- $msg = str_replace( "$1", $old, wfMsg( "filerenameerror" ) );
- $msg = str_replace( "$2", $new, $msg );
- $this->fatalError( $msg );
+ $this->fatalError( wfMsg( "filerenameerror", $old, $new ) );
}
function fileDeleteError( $name )
{
- $msg = str_replace( "$1", $name, wfMsg( "filedeleteerror" ) );
- $this->fatalError( $msg );
+ $this->fatalError( wfMsg( "filedeleteerror", $name ) );
}
function fileNotFoundError( $name )
{
- $msg = str_replace( "$1", $name, wfMsg( "filenotfound" ) );
- $this->fatalError( $msg );
+ $this->fatalError( wfMsg( "filenotfound", $name ) );
}
function returnToMain( $auto = true )
}
$link = $sk->makeKnownLink( $returnto, "" );
- $r = str_replace( "$1", $link, wfMsg( "returnto" ) );
+ $r = wfMsg( "returnto", $link );
if ( $auto ) {
$wgOut->addMeta( "http:Refresh", "10;url=" .
wfLocalUrlE( wfUrlencode( $returnto ) ) );
global $wgUser ;
$sk = $wgUser->getSkin() ;
$sql = "SELECT l_from FROM links WHERE l_to={$id}" ;
- $res = wfQuery ( $sql ) ;
+ $res = wfQuery ( $sql, DB_READ ) ;
while ( $x = wfFetchObject ( $res ) )
{
# $t = new Title ;
# $t = $t->getText() ;
$t = $x->l_from ;
$y = explode ( ":" , $t , 2 ) ;
- if ( count ( $y ) == 2 && $y[0] == $cat )
- {
+ if ( count ( $y ) == 2 && $y[0] == $cat ) {
array_push ( $children , $sk->makeLink ( $t , $y[1] ) ) ;
+ } else {
+ array_push ( $articles , $sk->makeLink ( $t ) ) ;
}
- else array_push ( $articles , $sk->makeLink ( $t ) ) ;
}
wfFreeResult ( $res ) ;
if ( count ( $articles ) > 0 )
{
asort ( $articles ) ;
- $h = str_replace ( "$1" , $ti[1] , wfMsg("category_header") ) ;
+ $h = wfMsg( "category_header", $ti[1] );
$r .= "<h2>{$h}</h2>\n" ;
$r .= implode ( ", " , $articles ) ;
}
return $r ;
}
+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",
+ /* 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 */
+ );
+return $htmlattrs ;
+}
+
+function fixTableTags ( $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",
+ "(in_array(strtolower(\"\$1\"),\$htmlattrs)?(\"\$1\".((\"x\$3\" != \"x\")?\"=\$3\":'')):'')",
+ $t);
+
+ return trim ( $t ) ;
+}
function doTableStuff ( $t )
{
$t = explode ( "\n" , $t ) ;
$td = array () ; # Is currently a td tag open?
+ $ltd = array () ; # Was it TD or TH?
$tr = array () ; # Is currently a tr tag open?
+ $ltr = array () ; # tr attributes
foreach ( $t AS $k => $x )
{
$x = rtrim ( $x ) ;
+ $fc = substr ( $x , 0 , 1 ) ;
if ( "{|" == substr ( $x , 0 , 2 ) )
{
- $t[$k] = "<table " . substr ( $x , 3 ) . ">" ;
+ $t[$k] = "<table " . $this->fixTableTags ( substr ( $x , 3 ) ) . ">" ;
array_push ( $td , false ) ;
+ array_push ( $ltd , "" ) ;
array_push ( $tr , false ) ;
+ array_push ( $ltr , "" ) ;
}
else if ( count ( $td ) == 0 ) { } # Don't do any of the following
else if ( "|}" == substr ( $x , 0 , 2 ) )
{
$z = "</table>\n" ;
+ $l = array_pop ( $ltd ) ;
if ( array_pop ( $tr ) ) $z = "</tr>" . $z ;
- if ( array_pop ( $td ) ) $z = "</td>" . $z ;
+ if ( array_pop ( $td ) ) $z = "</{$l}>" . $z ;
+ array_pop ( $ltr ) ;
$t[$k] = $z ;
}
- else if ( "|_" == substr ( $x , 0 , 2 ) ) # Caption
-{
-$z = trim ( substr ( $x , 2 ) ) ;
-$t[$k] = "<caption>{$z}</caption\n" ;
-}
+/* else if ( "|_" == substr ( $x , 0 , 2 ) ) # Caption
+ {
+ $z = trim ( substr ( $x , 2 ) ) ;
+ $t[$k] = "<caption>{$z}</caption>\n" ;
+ }*/
else if ( "|-" == substr ( $x , 0 , 2 ) ) # Allows for |---------------
{
+ $x = substr ( $x , 1 ) ;
+ 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 ( $td ) ) $z = "</td>" . $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 ( $ltr , $this->fixTableTags ( $x ) ) ;
}
- else if ( "|" == substr ( $x , 0 , 1 ) )
+ else if ( "|" == $fc || "!" == $fc || "|+" == substr ( $x , 0 , 2 ) ) # Caption
{
+ if ( "|+" == substr ( $x , 0 , 2 ) )
+ {
+ $fc = "+" ;
+ $x = substr ( $x , 1 ) ;
+ }
$after = substr ( $x , 1 ) ;
+ if ( $fc == "!" ) $after = str_replace ( "!!" , "||" , $after ) ;
$after = explode ( "||" , $after ) ;
$t[$k] = "" ;
foreach ( $after AS $theline )
{
$z = "" ;
- if ( !array_pop ( $tr ) ) $z = "<tr>\n" ;
+ $tra = array_pop ( $ltr ) ;
+ if ( !array_pop ( $tr ) ) $z = "<tr {$tra}>\n" ;
array_push ( $tr , true ) ;
- if ( array_pop ( $td ) ) $z = "</td>" . $z ;
+ 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 = "" ;
+ array_push ( $ltd , $l ) ;
$y = explode ( "|" , $theline , 2 ) ;
- if ( count ( $y ) == 1 ) $y = "{$z}<td>{$y[0]}" ;
- else $y = $y = "{$z}<td {$y[0]}>{$y[1]}" ;
+ if ( count ( $y ) == 1 ) $y = "{$z}<{$l}>{$y[0]}" ;
+ else $y = $y = "{$z}<{$l} ".$this->fixTableTags($y[0]).">{$y[1]}" ;
$t[$k] .= $y ;
array_push ( $td , true ) ;
}
}
}
+
+# Closing open td, tr && table
+while ( count ( $td ) > 0 )
+{
+if ( array_pop ( $td ) ) $t[] = "</td>" ;
+if ( array_pop ( $tr ) ) $t[] = "</tr>" ;
+$t[] = "</table>" ;
+}
+
$t = implode ( "\n" , $t ) ;
+# $t = $this->removeHTMLtags( $t );
return $t ;
}
function doWikiPass2( $text, $linestart )
{
global $wgUser, $wgLang, $wgUseDynamicDates;
- wfProfileIn( "OutputPage::doWikiPass2" );
+ $fname = "OutputPage::doWikiPass2";
+ wfProfileIn( $fname );
$text = $this->removeHTMLtags( $text );
$text = $this->replaceVariables( $text );
$text = $this->doBlockLevels( $text, $linestart );
if($wgUseDynamicDates) {
- $text = $wgLang->replaceDates( $text );
+ global $wgDateFormatter;
+ $text = $wgDateFormatter->reformat( $wgUser->getOption("date"), $text );
}
$text = $this->replaceExternalLinks( $text );
$sk = $wgUser->getSkin();
$text = $sk->transformContent( $text );
- $text .= $this->categoryMagic () ;
+ $text .= $this->categoryMagic () ;
- wfProfileOut();
+ wfProfileOut( $fname );
return $text;
}
/* private */ function replaceExternalLinks( $text )
{
- wfProfileIn( "OutputPage::replaceExternalLinks" );
+ $fname = "OutputPage::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, "gopher", false );
$text = $this->subReplaceExternalLinks( $text, "news", false );
$text = $this->subReplaceExternalLinks( $text, "mailto", false );
- wfProfileOut();
+ wfProfileOut( $fname );
return $text;
}
$s = array_shift( $a );
$s = substr( $s, 1 );
- $e1 = "/^([{$tc}]+)\\|([^]]+)]](.*)\$/sD";
- $e2 = "/^([{$tc}]+)]](.*)\$/sD";
- wfProfileOut();
+ $e1 = "/^([{$tc}]+)(?:\\|([^]]+))?]](.*)\$/sD";
+
+ # Special and Media are pseudo-namespaces; no pages actually exist in them
+ $image = Namespace::getImage();
+ $special = Namespace::getSpecial();
+ $media = Namespace::getMedia();
+ $nottalk = !Namespace::isTalk( $wgTitle->getNamespace() );
+ wfProfileOut( "$fname-setup" );
foreach ( $a as $line ) {
- wfProfileIn( "$fname-loop" );
- if ( preg_match( $e1, $line, $m ) ) { # page with alternate text
-
+ if ( preg_match( $e1, $line, $m ) ) { # page with normal text or alt
$text = $m[2];
$trail = $m[3];
-
- } else if ( preg_match( $e2, $line, $m ) ) { # page with normal text
-
- $text = "";
- $trail = $m[2];
- }
-
- else { # Invalid form; output directly
+ } else { # Invalid form; output directly
$s .= "[[" . $line ;
- wfProfileOut();
continue;
}
- if(substr($m[1],0,1)=="/") { # subpage
+
+ /* 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($wgNamespacesWithSubpages[$wgTitle->getNamespace()]) { # subpages allowed here
$link = $wgTitle->getPrefixedText(). "/" . trim($noslash);
- if(!$text) {
+ if( "" == $text ) {
$text= $m[1];
} # this might be changed for ugliness reasons
} else {
$link = $noslash; # no subpage allowed, use standard link
}
- } else { # no subpage
- $link = $m[1];
+ } elseif( $noforce ) { # no subpage
+ $link = $m[1];
+ } else {
+ $link = substr( $m[1], 1 );
}
+ if( "" == $text )
+ $text = $link;
- if ( preg_match( "/^((?:i|x|[a-z]{2,3})(?:-[a-z0-9]+)?|[A-Za-z\\x80-\\xff]+):(.*)\$/", $link, $m ) ) {
- $pre = strtolower( $m[1] );
- $suf = $m[2];
- if ( $wgLang->getNsIndex( $pre ) ==
- Namespace::getImage() ) {
- $nt = Title::newFromText( $suf );
- $name = $nt->getDBkey();
- if ( "" == $text ) { $text = $nt->GetText(); }
-
- $wgLinkCache->addImageLink( $name );
- $s .= $sk->makeImageLink( $name,
- wfImageUrl( $name ), $text );
+ $nt = Title::newFromText( $link );
+ if( !$nt ) {
+ $s .= "[[" . $line;
+ continue;
+ }
+ $ns = $nt->getNamespace();
+ $iw = $nt->getInterWiki();
+ if( $noforce ) {
+ if( $iw && $wgInterwikiMagic && $nottalk && $wgLang->getLanguageName( $iw ) ) {
+ array_push( $this->mLanguageLinks, $nt->getPrefixedText() );
$s .= $trail;
+/* CHECK MERGE @@@
} else if ( "media" == $pre ) {
$nt = Title::newFromText( $suf );
$name = $nt->getDBkey();
$s .= $sk->makeMediaLink( $name,
wfImageUrl( $name ), $text );
$s .= $trail;
- } else if ( isset($wgUseCategoryMagic) && $wgUseCategoryMagic && $pre == wfMsg ( "category" ) ) {
- $l = $sk->makeLink ( $pre.":".ucfirst($m[2]) , ucfirst ( $m[2] ) ) ;
- array_push ( $this->mCategoryLinks , $l ) ;
- $s .= $trail ;
+ } else if ( isset($wgUseCategoryMagic) && $wgUseCategoryMagic && $pre == wfMsg ( "category" ) ) {
+ $l = $sk->makeLink ( $pre.":".ucfirst( $m[2] ), ucfirst ( $m[2] ) ) ;
+ array_push ( $this->mCategoryLinks , $l ) ;
+ $s .= $trail ;
} else {
$l = $wgLang->getLanguageName( $pre );
- if ( "" == $l or !$wgInterwikiMagic or
- Namespace::isTalk( $wgTitle->getNamespace() ) ) {
- if ( "" == $text ) { $text = $link; }
+ if ( "" == $l or !$wgInterwikiMagic or Namespace::isTalk( $wgTitle->getNamespace() ) ) {
+ if ( "" == $text ) {
+ $text = $link;
+ }
$s .= $sk->makeLink( $link, $text, "", $trail );
} else if ( $pre != $wgLanguageCode ) {
array_push( $this->mLanguageLinks, "$pre:$suf" );
$s .= $trail;
}
+*/
+ continue;
+ }
+ if( $ns == $image ) {
+ $s .= $sk->makeImageLinkObj( $nt, $text ) . $trail;
+ $wgLinkCache->addImageLinkObj( $nt );
+ continue;
}
+/* CHECK MERGE @@@
# } else if ( 0 == strcmp( "##", substr( $link, 0, 2 ) ) ) {
# $link = substr( $link, 2 );
# $s .= "<a name=\"{$link}\">{$text}</a>{$trail}";
} else {
if ( "" == $text ) { $text = $link; }
+ # Hotspot:
$s .= $sk->makeLink( $link, $text, "", $trail );
+*/
+ }
+ if( $ns == $media ) {
+ $s .= $sk->makeMediaLinkObj( $nt, $text ) . $trail;
+ $wgLinkCache->addImageLinkObj( $nt );
+ continue;
+ } elseif( $ns == $special ) {
+ $s .= $sk->makeKnownLinkObj( $nt, $text, "", $trail );
+ continue;
}
- wfProfileOut();
+ $s .= $sk->makeLinkObj( $nt, $text, "", $trail );
}
- wfProfileOut();
+ wfProfileOut( $fname );
return $s;
}
/* private */ function doBlockLevels( $text, $linestart )
{
- wfProfileIn( "OutputPage::doBlockLevels" );
+ $fname = "OutputPage::doBlockLevels";
+ wfProfileIn( $fname );
# Parsing through the text line by line. The main thing
# happening here is handling of block-level elements p, pre,
# and making lists from lines starting with * # : etc.
}
$this->mLastSection = "";
}
- wfProfileOut();
+ wfProfileOut( $fname );
return $text;
}
/* private */ function replaceVariables( $text )
{
global $wgLang;
- wfProfileIn( "OutputPage:replaceVariables" );
+ $fname = "OutputPage::replaceVariables";
+ wfProfileIn( $fname );
- /* As with sigs, use server's local time --
- ensure this is appropriate for your audience! */
+
+ # Basic variables
+ # See Language.php for the definition of each magic word
+
+ # As with sigs, this uses the server's local time -- ensure
+ # this is appropriate for your audience!
$v = date( "m" );
$mw =& MagicWord::get( MAG_CURRENTMONTH );
$text = $mw->replace( $v, $text );
$v = wfNumberOfArticles();
$text = $mw->replace( $v, $text );
}
- wfProfileOut();
+
+ # "Variables" with an additional parameter e.g. {{MSG:wikipedia}}
+ # The callbacks are at the bottom of this file
+ $mw =& MagicWord::get( MAG_MSG );
+ $text = $mw->substituteCallback( $text, "wfReplaceMsgVar" );
+
+ $mw =& MagicWord::get( MAG_MSGNW );
+ $text = $mw->substituteCallback( $text, "wfReplaceMsgnwVar" );
+
+ wfProfileOut( $fname );
return $text;
}
+ # Cleans up HTML, removes dangerous tags and attributes
/* private */ function removeHTMLtags( $text )
{
- wfProfileIn( "OutputPage::removeHTMLtags" );
+ $fname = "OutputPage::removeHTMLtags";
+ wfProfileIn( $fname );
$htmlpairs = array( # Tags that must be closed
"b", "i", "u", "font", "big", "small", "sub", "sup", "h1",
"h2", "h3", "h4", "h5", "h6", "cite", "code", "em", "s",
$htmlsingle = array_merge( $tabletags, $htmlsingle );
$htmlelements = array_merge( $htmlsingle, $htmlpairs );
- $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",
- /* 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 */
- );
+ $htmlattrs = $this->getHTMLattrs () ;
# Remove HTML comments
$text = preg_replace( "/<!--.*-->/sU", "", $text );
$text .= "</$t>\n";
if ( $t == "table" ) { $tagstack = array_pop( $tablestack ); }
}
- wfProfileOut();
+ wfProfileOut( $fname );
return $text;
}
$es=$wgUser->getID() && $wgUser->getOption( "editsection" );
$esr=$wgUser->getID() && $wgUser->getOption( "editsectiononrightclick" );
}
- # if the string __NOTOC__ (not case-sensitive) occurs in the HTML, do not
- # add TOC
+
+ # Inhibit editsection links if requested in the page
+ if ($es) {
+ $esw=& MagicWord::get(MAG_NOEDITSECTION);
+ if ($esw->matchAndRemove( $text )) {
+ $es=0;
+ }
+ }
+ # if the string __NOTOC__ (not case-sensitive) occurs in the HTML,
+ # do not add TOC
$mw =& MagicWord::get( MAG_NOTOC );
- $st = ! $mw->matchAndRemove( $text );
+ if ($mw->matchAndRemove( $text ))
+ {
+ $st = 0;
+ }
# never add the TOC to the Main Page. This is an entry page that should not
# be more than 1-2 screens large anyway
}
}
+ // The canonized header is a version of the header text safe to use for links
$canonized_headline=preg_replace("/<.*?>/","",$headline); // strip out HTML
- $tocline=$canonized_headline;
+ $tocline = trim( $canonized_headline );
$canonized_headline=str_replace('"',"",$canonized_headline);
$canonized_headline=str_replace(" ","_",trim($canonized_headline));
$refer[$c]=$canonized_headline;
$refers[$canonized_headline]++; // count how many in assoc. array so we can track dupes in anchors
$refcount[$c]=$refers[$canonized_headline];
+
+ // Prepend the number to the heading text
+
if($nh||$st) {
$tocline=$numbering ." ". $tocline;
- if($nh) {
+
+ // Don't number the heading if it is the only one (looks silly)
+ if($nh && count($matches[3]) > 1) {
$headline=$numbering . " " . $headline; // the two are different if the line contains a link
- }
+ }
}
+
+ // Create the anchor for linking from the TOC to the section
+
$anchor=$canonized_headline;
if($refcount[$c]>1) {$anchor.="_".$refcount[$c];}
if($st) {
if($es && !isset($wpPreview)) {
$head[$c].=$sk->editSectionLink($c+1);
}
- $head[$c].="<H".$level.$matches[2][$c]
+
+ // Put it all together
+
+ $head[$c].="<h".$level.$matches[2][$c]
."<a name=\"".$anchor."\">"
.$headline
."</a>"
- ."</H".$level.">";
+ ."</h".$level.">";
+
+ // Add the edit section link
+
if($esr && !isset($wpPreview)) {
$head[$c]=$sk->editSectionScript($c+1,$head[$c]);
}
+
$numbering="";
$c++;
$dot=0;
$blocks=preg_split("/<H[1-6].*?>.*?<\/H[1-6]>/i",$text);
$i=0;
-
foreach($blocks as $block) {
if(($es) && !isset($wpPreview) && $c>0 && $i==0) {
# This is the [edit] link that appears for the top block of text when
# section editing is enabled
- $full.=$sk->editSectionLink(0);
+ $full.=$sk->editSectionLink(0);
}
$full.=$block;
if($st && $toclines>3 && !$i) {
$full.=$head[$i];
$i++;
}
+
return $full;
}
$a = split( "ISBN ", " $text" );
if ( count ( $a ) < 2 ) return $text;
$text = substr( array_shift( $a ), 1);
- $valid = "0123456789-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ $valid = "0123456789-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
foreach ( $a as $x ) {
$isbn = $blank = "" ;
while ( " " == $x{0} ) {
- $blank .= " ";
- $x = substr( $x, 1 );
+ $blank .= " ";
+ $x = substr( $x, 1 );
}
- while ( strstr( $valid, $x{0} ) != false ) {
+ 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 ) {
+ if ( "" == $num ) {
$text .= "ISBN $blank$x";
- } else {
+ } else {
$text .= "<a href=\"" . wfLocalUrlE( $wgLang->specialPage(
- "Booksources"), "isbn={$num}" ) . "\" CLASS=\"internal\">ISBN $isbn</a>";
+ "Booksources"), "isbn={$num}" ) . "\" class=\"internal\">ISBN $isbn</a>";
$text .= $x;
}
}
- return $text;
+ return $text;
}
/* private */ function magicRFC( $text )
}
}
+# Regex callbacks, used in OutputPage::replaceVariables
+
+# Just get rid of the dangerous stuff
+# Necessary because replaceVariables is called after removeHTMLtags,
+# and message text can come from any user
+function wfReplaceMsgVar( $matches ) {
+ global $wgOut;
+ $text = $wgOut->removeHTMLtags( wfMsg( $matches[1] ) );
+ return $text;
+}
+
+# Effective <nowiki></nowiki>
+# Not real <nowiki> because this is called after nowiki sections are processed
+function wfReplaceMsgnwVar( $matches ) {
+ $text = wfEscapeWikiText( wfMsg( $matches[1] ) );
+ return $text;
+}
+
?>