X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;ds=sidebyside;f=includes%2FOutputPage.php;h=5dd58a629df90e26d868995fb49eca62bd9f5926;hb=feb1eab8444bf79a6f162156d2614cb0009bbfa2;hp=7f1948affd2944ed477181a585f7c06e040c32cd;hpb=c6879704abf865e25554e9bd92b185f96097985d;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 7f1948affd..5dd58a629d 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -1,118 +1,7 @@ "; -} - -function renderMath( $tex ) -{ - global $wgUser, $wgMathDirectory, $wgTmpDirectory, $wgInputEncoding; - $mf = wfMsg( "math_failure" ); - $munk = wfMsg( "math_unknown_error" ); - - $fname = "renderMath"; - - $math = $wgUser->getOption("math"); - if ($math == 3) - return ('$ '.wfEscapeHTML($tex).' $'); - - $md5 = md5($tex); - $md5_sql = mysql_escape_string(pack("H32", $md5)); - if ($math == 0) - $sql = "SELECT math_outputhash FROM math WHERE math_inputhash = '".$md5_sql."'"; - else - $sql = "SELECT math_outputhash,math_html_conservativeness,math_html FROM math WHERE math_inputhash = '".$md5_sql."'"; - - $res = wfQuery( $sql, $fname ); - if ( wfNumRows( $res ) == 0 ) - { - $cmd = "./math/texvc ".escapeshellarg($wgTmpDirectory)." ". - escapeshellarg($wgMathDirectory)." ".escapeshellarg($tex)." ".escapeshellarg($wgInputEncoding); - $contents = `$cmd`; - - if (strlen($contents) == 0) - return "".$mf." (".$munk."): ".wfEscapeHTML($tex).""; - $retval = substr ($contents, 0, 1); - if (($retval == "C") || ($retval == "M") || ($retval == "L")) { - if ($retval == "C") - $conservativeness = 2; - else if ($retval == "M") - $conservativeness = 1; - else - $conservativeness = 0; - $outdata = substr ($contents, 33); - - $i = strpos($outdata, "\000"); - - $outhtml = substr($outdata, 0, $i); - $mathml = substr($outdata, $i+1); - - $sql_html = "'".mysql_escape_string($outhtml)."'"; - $sql_mathml = "'".mysql_escape_string($mathml)."'"; - } else if (($retval == "c") || ($retval == "m") || ($retval == "l")) { - $outhtml = substr ($contents, 33); - if ($retval == "c") - $conservativeness = 2; - else if ($retval == "m") - $conservativeness = 1; - else - $conservativeness = 0; - $sql_html = "'".mysql_escape_string($outhtml)."'"; - $mathml = ''; - $sql_mathml = 'NULL'; - } else if ($retval == "X") { - $outhtml = ''; - $mathml = substr ($contents, 33); - $sql_html = 'NULL'; - $sql_mathml = "'".mysql_escape_string($mathml)."'"; - $conservativeness = 0; - } else if ($retval == "+") { - $outhtml = ''; - $mathml = ''; - $sql_html = 'NULL'; - $sql_mathml = 'NULL'; - $conservativeness = 0; - } else { - if ($retval == "E") - $errmsg = wfMsg( "math_lexing_error" ); - else if ($retval == "S") - $errmsg = wfMsg( "math_syntax_error" ); - else if ($retval == "F") - $errmsg = wfMsg( "math_unknown_function" ); - else - $errmsg = $munk; - return "

".$mf." (".$errmsg.substr($contents, 1)."): ".wfEscapeHTML($tex)."

"; - } - - $outmd5 = substr ($contents, 1, 32); - if (!preg_match("/^[a-f0-9]{32}$/", $outmd5)) - return "".$mf." (".$munk."): ".wfEscapeHTML($tex).""; - - $outmd5_sql = mysql_escape_string(pack("H32", $outmd5)); - - $sql = "REPLACE INTO math VALUES ('".$md5_sql."', '".$outmd5_sql."', ".$conservativeness.", ".$sql_html.", ".$sql_mathml.")"; - - $res = wfQuery( $sql, $fname ); - # we don't really care if it fails - - if (($math == 0) || ($rpage->math_html == '') || (($math == 1) && ($conservativeness != 2)) || (($math == 4) && ($conservativeness == 0))) - return linkToMathImage($tex, $outmd5); - else - return $outhtml; - } else { - $rpage = wfFetchObject ( $res ); - $outputhash = unpack( "H32md5", $rpage->math_outputhash . " " ); - $outputhash = $outputhash ['md5']; - - if (($math == 0) || ($rpage->math_html == '') || (($math == 1) && ($rpage->math_html_conservativeness != 2)) || (($math == 4) && ($rpage->math_html_conservativeness == 0))) - return linkToMathImage ( $tex, $outputhash ); - else - return $rpage->math_html; - } -} +if($wgUseTeX) include_once( "Math.php" ); class OutputPage { var $mHeaders, $mCookies, $mMetatags, $mKeywords; @@ -123,6 +12,8 @@ class OutputPage { var $mDTopen, $mLastSection; # Used for processing DL, PRE var $mLanguageLinks, $mSupressQuickbar; + var $mOnloadHandler; + var $mDoNothing; function OutputPage() { @@ -130,12 +21,14 @@ class 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" ) ; } @@ -147,6 +40,10 @@ class OutputPage { 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; @@ -167,9 +64,13 @@ class OutputPage { $lastmod = gmdate( "D, j M Y H:i:s", wfTimestamp2Unix( max( $timestamp, $wgUser->mTouched ) ) ) . " GMT"; - if( $_SERVER["HTTP_IF_MODIFIED_SINCE"] != "" ) { - $ismodsince = wfUnix2Timestamp( strtotime( $_SERVER["HTTP_IF_MODIFIED_SINCE"] ) ); - wfDebug( "-- client send If-Modified-Since: " . $_SERVER["HTTP_IF_MODIFIED_SINCE"] . "\n", false ); + 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"] ); + $ismodsince = wfUnix2Timestamp( strtotime( $modsince ) ); + wfDebug( "-- client send If-Modified-Since: " . $modsince . "\n", false ); wfDebug( "-- we might send Last-Modified : $lastmod\n", false ); if( ($ismodsince >= $timestamp ) and $wgUser->validateCache( $ismodsince ) ) { @@ -179,7 +80,8 @@ class OutputPage { 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; @@ -200,32 +102,15 @@ class OutputPage { 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; } @@ -240,7 +125,8 @@ class OutputPage { function addWikiText( $text, $linestart = true ) { global $wgUseTeX; - wfProfileIn( "OutputPage::addWikiText" ); + $fname = "OutputPage::addWikiText"; + wfProfileIn( $fname ); $unique = "3iyZiyA7iMwg5rhxP0Dcc9oTnj8qD1jm1Sfv4"; $unique2 = "4LIQ9nXtiYFPCSfitVwDw7EYwQlL4GeeQ7qSO"; $unique3 = "fPaA8gDfdLBqzj68Yjg9Hil3qEF8JGO0uszIp"; @@ -262,7 +148,7 @@ class OutputPage { $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]; } } @@ -276,7 +162,7 @@ class OutputPage { $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]; } } @@ -292,7 +178,7 @@ class OutputPage { $q = preg_split( "/<\\/\\s*pre\\s*>/i", $p[1], 2 ); ++$presecs; $prelist[$presecs] = "
". wfEscapeHTMLTagsOnly($q[0]). "
"; - $stripped3 .= $unique3; + $stripped3 .= $unique3 . $presecs . "s"; $stripped2 = $q[1]; } } @@ -302,34 +188,38 @@ class OutputPage { $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 $wgUseGzip; if( $this->mLastModified != "" ) { wfDebug( "** private caching; {$this->mLastModified} **\n", false ); header( "Cache-Control: private, must-revalidate, max-age=0" ); - header( "Vary: Accept-Encoding" ); header( "Last-modified: {$this->mLastModified}" ); + if( $wgUseGzip ) { + # We should put in Accept-Encoding, but IE chokes on anything but + # User-Agent in a Vary: header (at least through 6.0) + header( "Vary: User-Agent" ); + } } else { wfDebug( "** no caching **\n", false ); header( "Cache-Control: no-cache" ); # Experimental - see below header( "Pragma: no-cache" ); - header( "Vary: Accept-Encoding" ); header( "Last-modified: " . gmdate( "D, j M Y H:i:s" ) . " GMT" ); } header( "Expires: Mon, 15 Jan 2001 00:00:00 GMT" ); # Cachers always validate the page! @@ -342,18 +232,26 @@ class OutputPage { { 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; } @@ -361,36 +259,8 @@ class OutputPage { foreach( $this->mCookies as $name => $val ) { setcookie( $name, $val, $exp, "/" ); } - wfProfileOut(); - - wfProfileIn( "OutputPage::output-middle" ); - $sk->initPage(); - $this->out( $this->headElement() ); - $this->out( "\ngetBodyOptions(); - foreach ( $ops as $name => $val ) { - $this->out( " $name='$val'" ); - } - $this->out( ">\n" ); - if ( $wgDebugComments ) { - $this->out( "\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" ); + $sk->outputPage( $this ); flush(); } @@ -408,22 +278,26 @@ class OutputPage { 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 = "*"; @@ -446,13 +320,15 @@ class OutputPage { # 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; @@ -460,45 +336,6 @@ class OutputPage { 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( "", $elapsed ); return $com; @@ -522,7 +359,7 @@ class OutputPage { $this->returnToMain( false ); $this->output(); - exit; + wfAbruptExit(); } function sysopRequired() @@ -537,8 +374,7 @@ class OutputPage { $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(); } @@ -554,54 +390,67 @@ class OutputPage { $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() + 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" ) ); - $this->addHTML( $text ); + 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 .= "

\n"; + $this->addHTML( $text ); + } + $this->returnToMain( false ); } @@ -613,40 +462,32 @@ class OutputPage { $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 ) @@ -659,7 +500,7 @@ class OutputPage { } $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 ) ) ); @@ -668,62 +509,189 @@ class OutputPage { } -function categoryMagic () + function categoryMagic () + { + global $wgTitle , $wgUseCategoryMagic ; + if ( !isset ( $wgUseCategoryMagic ) || !$wgUseCategoryMagic ) return ; + $id = $wgTitle->getArticleID() ; + $cat = ucfirst ( wfMsg ( "category" ) ) ; + $ti = $wgTitle->getText() ; + $ti = explode ( ":" , $ti , 2 ) ; + if ( $cat != $ti[0] ) return "" ; + $r = "
\n" ; + + $articles = array() ; + $parents = array () ; + $children = array() ; + + + global $wgUser ; + $sk = $wgUser->getSkin() ; + $sql = "SELECT l_from FROM links WHERE l_to={$id}" ; + $res = wfQuery ( $sql, DB_READ ) ; + while ( $x = wfFetchObject ( $res ) ) + { + # $t = new Title ; + # $t->newFromDBkey ( $x->l_from ) ; + # $t = $t->getText() ; + $t = $x->l_from ; + $y = explode ( ":" , $t , 2 ) ; + if ( count ( $y ) == 2 && $y[0] == $cat ) { + array_push ( $children , $sk->makeLink ( $t , $y[1] ) ) ; + } else { + array_push ( $articles , $sk->makeLink ( $t ) ) ; + } + } + wfFreeResult ( $res ) ; + + # Children + if ( count ( $children ) > 0 ) + { + asort ( $children ) ; + $r .= "

".wfMsg("subcategories")."

\n" ; + $r .= implode ( ", " , $children ) ; + } + + # Articles + if ( count ( $articles ) > 0 ) + { + asort ( $articles ) ; + $h = wfMsg( "category_header", $ti[1] ); + $r .= "

{$h}

\n" ; + $r .= implode ( ", " , $articles ) ; + } + + + return $r ; + } + +function getHTMLattrs () { -global $wgTitle , $wgUseCategoryMagic ; -if ( !isset ( $wgUseCategoryMagic ) || !$wgUseCategoryMagic ) return ; -$id = $wgTitle->getArticleID() ; -$cat = ucfirst ( wfMsg ( "category" ) ) ; -$ti = $wgTitle->getText() ; -$ti = explode ( ":" , $ti , 2 ) ; -if ( $cat != $ti[0] ) return "" ; -$r = "
\n" ; - -$articles = array() ; -$parents = array () ; -$children = array() ; - - -global $wgUser ; -$sk = $wgUser->getSkin() ; -$sql = "SELECT l_from FROM links WHERE l_to={$id}" ; -$res = wfQuery ( $sql ) ; -while ( $x = wfFetchObject ( $res ) ) + $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 ) { -# $t = new Title ; -# $t->newFromDBkey ( $x->l_from ) ; -# $t = $t->getText() ; - $t = $x->l_from ; - $y = explode ( ":" , $t , 2 ) ; - if ( count ( $y ) == 2 && $y[0] == $cat ) + 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 ) { - array_push ( $children , $sk->makeLink ( $t , $y[1] ) ) ; + $x = rtrim ( $x ) ; + $fc = substr ( $x , 0 , 1 ) ; + if ( "{|" == substr ( $x , 0 , 2 ) ) + { + $t[$k] = "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 = "
\n" ; + $l = array_pop ( $ltd ) ; + if ( array_pop ( $tr ) ) $z = "" . $z ; + if ( array_pop ( $td ) ) $z = "" . $z ; + array_pop ( $ltr ) ; + $t[$k] = $z ; + } +/* else if ( "|_" == substr ( $x , 0 , 2 ) ) # Caption + { + $z = trim ( substr ( $x , 2 ) ) ; + $t[$k] = "{$z}\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 = "" . $z ; + if ( array_pop ( $td ) ) $z = "" . $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 ( "|" == $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 = "" ; + $tra = array_pop ( $ltr ) ; + if ( !array_pop ( $tr ) ) $z = "\n" ; + array_push ( $tr , true ) ; + array_push ( $ltr , "" ) ; + + $l = array_pop ( $ltd ) ; + if ( array_pop ( $td ) ) $z = "" . $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}<{$l}>{$y[0]}" ; + else $y = $y = "{$z}<{$l} ".$this->fixTableTags($y[0]).">{$y[1]}" ; + $t[$k] .= $y ; + array_push ( $td , true ) ; + } + } } - else array_push ( $articles , $sk->makeLink ( $t ) ) ; -} -wfFreeResult ( $res ) ; - -# Children - if ( count ( $children ) > 0 ) - { - asort ( $children ) ; - $r .= "

".wfMsg("subcategories")."

\n" ; - $r .= implode ( ", " , $children ) ; - } - -# Articles - if ( count ( $articles ) > 0 ) - { - asort ( $articles ) ; - $h = str_replace ( "$1" , $ti[1] , wfMsg("category_header") ) ; - $r .= "

{$h}

\n" ; - $r .= implode ( ", " , $articles ) ; - } - - -return $r ; + +# Closing open td, tr && table +while ( count ( $td ) > 0 ) +{ +if ( array_pop ( $td ) ) $t[] = "" ; +if ( array_pop ( $tr ) ) $t[] = "" ; +$t[] = "" ; } + $t = implode ( "\n" , $t ) ; +# $t = $this->removeHTMLtags( $t ); + return $t ; +} # Well, OK, it's actually about 14 passes. But since all the # hard lifting is done inside PHP's regex code, it probably @@ -732,7 +700,8 @@ return $r ; function doWikiPass2( $text, $linestart ) { global $wgUser, $wgLang, $wgUseDynamicDates; - wfProfileIn( "OutputPage::doWikiPass2" ); + $fname = "OutputPage::doWikiPass2"; + wfProfileIn( $fname ); $text = $this->removeHTMLtags( $text ); $text = $this->replaceVariables( $text ); @@ -745,11 +714,13 @@ return $r ; $text = $this->doBlockLevels( $text, $linestart ); if($wgUseDynamicDates) { - $text = $wgLang->replaceDates( $text ); + global $wgDateFormatter; + $text = $wgDateFormatter->reformat( $wgUser->getOption("date"), $text ); } $text = $this->replaceExternalLinks( $text ); $text = $this->replaceInternalLinks ( $text ); + $text = $this->doTableStuff ( $text ) ; $text = $this->magicISBN( $text ); $text = $this->magicRFC( $text ); @@ -757,9 +728,9 @@ return $r ; $sk = $wgUser->getSkin(); $text = $sk->transformContent( $text ); - $text .= $this->categoryMagic () ; + $text .= $this->categoryMagic () ; - wfProfileOut(); + wfProfileOut( $fname ); return $text; } @@ -837,14 +808,15 @@ return $r ; /* 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; } @@ -918,7 +890,7 @@ return $r ; /* private */ function replaceInternalLinks( $s ) { global $wgTitle, $wgUser, $wgLang; - global $wgLinkCache, $wgInterwikiMagic; + global $wgLinkCache, $wgInterwikiMagic, $wgUseCategoryMagic; global $wgNamespacesWithSubpages, $wgLanguageCode; wfProfileIn( $fname = "OutputPage::replaceInternalLinks" ); @@ -930,60 +902,67 @@ return $r ; $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" ); - wfProfileIn( "$fname-loop" ); foreach ( $a as $line ) { - 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 ; 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(); @@ -993,27 +972,50 @@ return $r ; $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 { $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 .= "{$text}{$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; + } + $s .= $sk->makeLinkObj( $nt, $text, "", $trail ); } - wfProfileOut(); - wfProfileOut(); + wfProfileOut( $fname ); return $s; } @@ -1096,7 +1098,8 @@ return $r ; /* 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. @@ -1195,43 +1198,73 @@ return $r ; } $this->mLastSection = ""; } - wfProfileOut(); + wfProfileOut( $fname ); return $text; } /* private */ function replaceVariables( $text ) { global $wgLang; - wfProfileIn( "OutputPage:replaceVariables" ); + $fname = "OutputPage::replaceVariables"; + wfProfileIn( $fname ); + + + # Basic variables + # See Language.php for the definition of each magic word - /* As with sigs, use server's local time -- - ensure this is appropriate for your audience! */ + # As with sigs, this uses the server's local time -- ensure + # this is appropriate for your audience! $v = date( "m" ); - $text = str_replace( "{{CURRENTMONTH}}", $v, $text ); + $mw =& MagicWord::get( MAG_CURRENTMONTH ); + $text = $mw->replace( $v, $text ); + $v = $wgLang->getMonthName( date( "n" ) ); - $text = str_replace( "{{CURRENTMONTHNAME}}", $v, $text ); + $mw =& MagicWord::get( MAG_CURRENTMONTHNAME ); + $text = $mw->replace( $v, $text ); + $v = $wgLang->getMonthNameGen( date( "n" ) ); - $text = str_replace( "{{CURRENTMONTHNAMEGEN}}", $v, $text ); + $mw =& MagicWord::get( MAG_CURRENTMONTHNAMEGEN ); + $text = $mw->replace( $v, $text ); + $v = date( "j" ); - $text = str_replace( "{{CURRENTDAY}}", $v, $text ); + $mw = MagicWord::get( MAG_CURRENTDAY ); + $text = $mw->replace( $v, $text ); + $v = $wgLang->getWeekdayName( date( "w" )+1 ); - $text = str_replace( "{{CURRENTDAYNAME}}", $v, $text ); + $mw =& MagicWord::get( MAG_CURRENTDAYNAME ); + $text = $mw->replace( $v, $text ); + $v = date( "Y" ); - $text = str_replace( "{{CURRENTYEAR}}", $v, $text ); + $mw =& MagicWord::get( MAG_CURRENTYEAR ); + $text = $mw->replace( $v, $text ); + $v = $wgLang->time( wfTimestampNow(), false ); - $text = str_replace( "{{CURRENTTIME}}", $v, $text ); + $mw =& MagicWord::get( MAG_CURRENTTIME ); + $text = $mw->replace( $v, $text ); - if ( false !== strstr( $text, "{{NUMBEROFARTICLES}}" ) ) { + $mw =& MagicWord::get( MAG_NUMBEROFARTICLES ); + if ( $mw->match( $text ) ) { $v = wfNumberOfArticles(); - $text = str_replace( "{{NUMBEROFARTICLES}}", $v, $text ); + $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", @@ -1253,18 +1286,7 @@ return $r ; $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 ); @@ -1329,7 +1351,7 @@ return $r ; $text .= "\n"; if ( $t == "table" ) { $tagstack = array_pop( $tablestack ); } } - wfProfileOut(); + wfProfileOut( $fname ); return $text; } @@ -1358,11 +1380,20 @@ return $r ; $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 - if(preg_match("/__NOTOC__/i",$text)) { - $text=preg_replace("/__NOTOC__/i","",$text); - $st=0; + + # 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 ); + if ($mw->matchAndRemove( $text )) + { + $st = 0; } # never add the TOC to the Main Page. This is an entry page that should not @@ -1409,20 +1440,29 @@ return $r ; } } + // 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) { @@ -1431,14 +1471,21 @@ return $r ; if($es && !isset($wpPreview)) { $head[$c].=$sk->editSectionLink($c+1); } - $head[$c].="" .$headline ."" - .""; + .""; + + // Add the edit section link + if($esr && !isset($wpPreview)) { $head[$c]=$sk->editSectionScript($c+1,$head[$c]); } + $numbering=""; $c++; $dot=0; @@ -1455,12 +1502,11 @@ return $r ; $blocks=preg_split("/.*?<\/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) { @@ -1471,6 +1517,7 @@ return $r ; $full.=$head[$i]; $i++; } + return $full; } @@ -1481,30 +1528,30 @@ return $r ; $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 .= "specialPage( - "Booksources"), "isbn={$num}" ) . "\" CLASS=\"internal\">ISBN $isbn"; + "Booksources"), "isbn={$num}" ) . "\" class=\"internal\">ISBN $isbn"; $text .= $x; } } - return $text; + return $text; } /* private */ function magicRFC( $text ) @@ -1556,4 +1603,22 @@ return $r ; } } +# 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 +# Not real because this is called after nowiki sections are processed +function wfReplaceMsgnwVar( $matches ) { + $text = wfEscapeWikiText( wfMsg( $matches[1] ) ); + return $text; +} + ?>