From: Arne Heizmann Date: Thu, 8 Jul 2004 14:53:54 +0000 (+0000) Subject: This commit implements Josh Cogliati's "info" feature (e.g. X-Git-Tag: 1.5.0alpha1~2712 X-Git-Url: http://git.cyclocoop.org/%24href?a=commitdiff_plain;h=6deed7d83e4335873b2565897ae01f79cc8d17eb;p=lhc%2Fweb%2Fwiklou.git This commit implements Josh Cogliati's "info" feature (e.g. http://en.wikipedia.org/w/wiki.phtml?title=Wikipedia&action=info), fixes the page headings for protect/unprotect, and does a lot of whitespace changes (sorry about that). I've also fixed confusing indentation somewhere. --- diff --git a/includes/Article.php b/includes/Article.php index 5bbc6d2a6f..ce6e1b02ed 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -16,12 +16,12 @@ class Article { /* private */ var $mMinorEdit, $mRedirectedFrom; /* private */ var $mTouched, $mFileCache, $mTitle; /* private */ var $mId, $mTable; - + function Article( &$title ) { $this->mTitle =& $title; $this->clear(); } - + /* private */ function clear() { $this->mContentLoaded = false; @@ -62,7 +62,7 @@ class Article { } return $text; } - + /* static */ function compressRevisionText( &$text ) { global $wgCompressRevisions; if( !$wgCompressRevisions ) { @@ -75,7 +75,7 @@ class Article { $text = gzdeflate( $text ); return 'gzip'; } - + # Returns the text associated with a "link" type old table row /* static */ function followLink( $link ) { # Split the link into fields and values @@ -119,7 +119,7 @@ class Article { global $wgLoadBalancer; $fname = 'fetchFromLocation'; wfProfileIn( $fname ); - + $p = strpos( $location, ':' ); if ( $p === false ) { wfProfileOut( $fname ); @@ -132,7 +132,7 @@ class Article { case 'mysql': # MySQL locations are specified by mysql:///// # Machine ID 0 is the current connection - if ( preg_match( '/^mysql:\/\/(\d+)\/([A-Za-z_]+)\/([A-Za-z_]+)\/([A-Za-z_]+)$/', + if ( preg_match( '/^mysql:\/\/(\d+)\/([A-Za-z_]+)\/([A-Za-z_]+)\/([A-Za-z_]+)$/', $location, $matches ) ) { $machineID = $matches[1]; $dbName = $matches[2]; @@ -144,11 +144,11 @@ class Article { } 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'], + $db = Database::newFromParams( $params['server'], $params['user'], $params['password'], $dbName, 1, false, true, true ); } } @@ -244,15 +244,15 @@ class Article { } } } - + # This function returns the text of a section, specified by a number ($section). - # A section is text under a heading like == Heading == or

Heading

, or + # A section is text under a heading like == Heading == or

Heading

, or # the first section before any such heading (section 0). # # If a section contains subsections, these are also returned. # function getSection($text,$section) { - + # strip NOWIKI etc. to avoid confusion (true-parameter causes HTML # comments to be stripped as well) $striparray=array(); @@ -273,23 +273,23 @@ class Article { $headline=$secs[$section*2-1]; preg_match( '/^(=+).*?=+|^.*?<\/h[1-6].*?' . '>/mi',$headline,$matches); $hlevel=$matches[1]; - + # translate wiki heading into level if(strpos($hlevel,'=')!==false) { - $hlevel=strlen($hlevel); + $hlevel=strlen($hlevel); } - + $rv=$headline. $secs[$section*2]; $count=$section+1; - + $break=false; while(!empty($secs[$count*2-1]) && !$break) { - + $subheadline=$secs[$count*2-1]; preg_match( '/^(=+).*?=+|^.*?<\/h[1-6].*?' . '>/mi',$subheadline,$matches); $subhlevel=$matches[1]; if(strpos($subhlevel,'=')!==false) { - $subhlevel=strlen($subhlevel); + $subhlevel=strlen($subhlevel); } if($subhlevel > $hlevel) { $rv.=$subheadline.$secs[$count*2]; @@ -298,7 +298,7 @@ class Article { $break=true; } $count++; - + } } # reinsert stripped tags @@ -308,7 +308,7 @@ class Article { return $rv; } - + # Load the revision (including cur_text) into this object function loadContent( $noredir = false ) @@ -321,21 +321,21 @@ class Article { if ( $this->mContentLoaded ) return; $fname = 'Article::loadContent'; - - # Pre-fill content with error message so that if something + + # Pre-fill content with error message so that if something # fails we'll have something telling us what we intended. - $t = $this->mTitle->getPrefixedText(); - if ( isset( $oldid ) ) { - $oldid = IntVal( $oldid ); + $t = $this->mTitle->getPrefixedText(); + if ( isset( $oldid ) ) { + $oldid = IntVal( $oldid ); $t .= ",oldid={$oldid}"; - } - if ( isset( $redirect ) ) { - $redirect = ($redirect == 'no') ? 'no' : 'yes'; - $t .= ",redirect={$redirect}"; - } + } + if ( isset( $redirect ) ) { + $redirect = ($redirect == 'no') ? 'no' : 'yes'; + $t .= ",redirect={$redirect}"; + } $this->mContent = wfMsg( 'missingarticle', $t ); - + if ( ! $oldid ) { # Retrieve current version $id = $this->getID(); if ( 0 == $id ) return; @@ -345,8 +345,8 @@ class Article { "FROM cur WHERE cur_id={$id}"; wfDebug( "$sql\n" ); $res = wfQuery( $sql, DB_READ, $fname ); - if ( 0 == wfNumRows( $res ) ) { - return; + if ( 0 == wfNumRows( $res ) ) { + return; } $s = wfFetchObject( $res ); @@ -361,7 +361,7 @@ class Article { # Gotta hand redirects to special pages differently: # Fill the HTTP response "Location" header and ignore # the rest of the page we're on. - + if ( $rt->getInterwiki() != '' ) { $wgOut->redirect( $rt->getFullURL() ) ; return; @@ -375,7 +375,7 @@ class Article { $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 ); - + if ( 0 != wfNumRows( $res ) ) { $this->mRedirectedFrom = $this->mTitle->getPrefixedText(); $this->mTitle = $rt; @@ -434,9 +434,9 @@ class Article { return $this->mContent; } $this->mContent = false; - + $fname = 'Article::loadContent'; - + if ( ! $oldid ) { # Retrieve current version $id = $this->getID(); if ( 0 == $id ) { @@ -447,8 +447,8 @@ class Article { '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 ) ) { - return false; + if ( 0 == wfNumRows( $res ) ) { + return false; } $s = wfFetchObject( $res ); @@ -464,7 +464,7 @@ class Article { $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 ); - + if ( 0 != wfNumRows( $res ) ) { $this->mRedirectedFrom = $this->mTitle->getPrefixedText(); $this->mTitle = $rt; @@ -488,8 +488,8 @@ class Article { $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 ) ) { - return false; + if ( 0 == wfNumRows( $res ) ) { + return false; } $s = wfFetchObject( $res ); @@ -526,7 +526,7 @@ class Article { function isCountable( $text ) { global $wgUseCommaCount, $wgMwRedir; - + if ( 0 != $this->mTitle->getNamespace() ) { return 0; } if ( $wgMwRedir->matchStart( $text ) ) { return 0; } $token = ($wgUseCommaCount ? ',' : '[[' ); @@ -592,7 +592,7 @@ class Article { $fname = 'Article::getContributors'; # XXX: this is expensive; cache this info somewhere. - + $title = $this->mTitle; $contribs = array(); @@ -602,8 +602,8 @@ class Article { ' FROM old LEFT JOIN user ON old.old_user = user.user_id ' . ' WHERE old.old_namespace = ' . $title->getNamespace() . ' AND old.old_title = "' . $title->getDBkey() . '"' . - ' AND old.old_user != ' . $this->getUser() . - ' GROUP BY old.old_user ' . + ' AND old.old_user != ' . $this->getUser() . + ' GROUP BY old.old_user ' . ' ORDER BY timestamp DESC '; if ($limit > 0) { @@ -611,16 +611,16 @@ class Article { } $res = wfQuery($sql, DB_READ, $fname); - + while ( $line = wfFetchObject( $res ) ) { $contribs[] = array($line->old_user, $line->old_user_text, $line->user_real_name); } - + wfFreeResult($res); - + return $contribs; } - + # This is the default action of the script: just view the page of # the given title. @@ -628,7 +628,7 @@ class Article { { global $wgUser, $wgOut, $wgLang, $wgRequest; global $wgLinkCache, $IP, $wgEnableParserCache; - + $fname = 'Article::view'; wfProfileIn( $fname ); @@ -660,14 +660,14 @@ class Article { return; } } - + # Should the parser cache be used? if ( $wgEnableParserCache && intval($wgUser->getOption( 'stubthreshold' )) == 0 && empty( $oldid ) ) { $pcache = true; } else { $pcache = false; } - + $outputDone = false; if ( $pcache ) { if ( $wgOut->tryParserCache( $this, $wgUser ) ) { @@ -677,14 +677,14 @@ class Article { 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; } - + # We're looking at an old revision @@ -698,8 +698,8 @@ class Article { 'redirect=no' ); $s = wfMsg( 'redirectedfrom', $redir ); $wgOut->setSubtitle( $s ); - - # Can't cache redirects + + # Can't cache redirects $pcache = false; } @@ -707,8 +707,8 @@ class Article { # 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() && + if ( + $this->mTitle->getNamespace() == Namespace::getUser() && preg_match('/\\/[\\w]+\\.(css|js)$/', $this->mTitle->getDBkey()) ) { $wgOut->addWikiText( wfMsg('clearyourcache')); @@ -720,7 +720,7 @@ class Article { } } $wgOut->setPageTitle( $this->mTitle->getPrefixedText() ); - + # Add link titles as META keywords $wgOut->addMetaTags() ; @@ -737,7 +737,7 @@ class Article { { global $wgOut, $wgUser, $wgLinkCache, $wgMwRedir; global $wgUseSquid, $wgDeferredUpdateList, $wgInternalServer, $wgIsPg, $wgIsMySQL; - + $fname = 'Article::insertNewArticle'; $this->mCountAdjustment = $this->isCountable( $text ); @@ -752,7 +752,7 @@ class Article { $won = wfInvertTimestamp( $now ); wfSeedRandom(); $rand = number_format( mt_rand() / mt_getrandmax(), 12, '.', '' ); - + if ($wgIsPg) { $cur_id_column="cur_id,"; $cur_id=wfGetSQL(""," nextval('cur_cur_id_seq')"); @@ -780,20 +780,20 @@ class Article { Article::onArticleCreate( $this->mTitle ); RecentChange::notifyNew( $now, $this->mTitle, $isminor, $wgUser, $summary ); - - if ($watchthis) { - if(!$this->mTitle->userIsWatching()) $this->watch(); + + if ($watchthis) { + if(!$this->mTitle->userIsWatching()) $this->watch(); } else { if ( $this->mTitle->userIsWatching() ) { $this->unwatch(); } } - + # The talk page isn't in the regular link tables, so we need to update manually: $talkns = $ns ^ 1; # talk -> normal; normal -> talk $sql = "UPDATE cur set cur_touched='$now' WHERE cur_namespace=$talkns AND cur_title='" . wfStrencode( $ttl ) . "'"; wfQuery( $sql, DB_WRITE ); - + # standard deferred updates $this->editUpdates( $text ); @@ -804,7 +804,7 @@ class Article { /* Side effects: loads last edit */ function getTextOfLastEditWithSectionReplacedOrAdded($section, $text, $summary = ''){ $this->loadLastEdit(); - $oldtext = $this->getContent( true ); + $oldtext = $this->getContent( true ); if ($section != '') { if($section=='new') { if($summary) $subject="== {$summary} ==\n\n"; @@ -825,10 +825,10 @@ class Article { $secs=preg_split('/(^=+.*?=+|^.*?<\/h[1-6].*?' . '>)/mi', $oldtext,-1,PREG_SPLIT_DELIM_CAPTURE); $secs[$section*2]=$text."\n\n"; // replace with edited - + # section 0 is top (intro) section - if($section!=0) { - + if($section!=0) { + # headline of old section - we need to go through this section # to determine if there are any subsections that now need to # be erased, as the mother section has been replaced with @@ -836,23 +836,23 @@ class Article { $headline=$secs[$section*2-1]; preg_match( '/^(=+).*?=+|^.*?<\/h[1-6].*?' . '>/mi',$headline,$matches); $hlevel=$matches[1]; - + # determine headline level for wikimarkup headings if(strpos($hlevel,'=')!==false) { - $hlevel=strlen($hlevel); + $hlevel=strlen($hlevel); } - + $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].*?' . '>/mi',$subheadline,$matches); $subhlevel=$matches[1]; if(strpos($subhlevel,'=')!==false) { - $subhlevel=strlen($subhlevel); + $subhlevel=strlen($subhlevel); } if($subhlevel > $hlevel) { // erase old subsections @@ -863,16 +863,16 @@ class Article { $break=true; } $count++; - + } - + } $text=join('',$secs); # reinsert the stuff that we stripped out earlier - $text=$parser->unstrip($text,$striparray); - $text=$parser->unstripNoWiki($text,$striparray); + $text=$parser->unstrip($text,$striparray); + $text=$parser->unstripNoWiki($text,$striparray); } - + } return $text; } @@ -886,7 +886,7 @@ class Article { $fname = 'Article::updateArticle'; if ( $this->mMinorEdit ) { $me1 = 1; } else { $me1 = 0; } - if ( $minor && $wgUser->getID() ) { $me2 = 1; } else { $me2 = 0; } + if ( $minor && $wgUser->getID() ) { $me2 = 1; } else { $me2 = 0; } if ( preg_match( "/^((" . $wgMwRedir->getBaseRegex() . ')[^\\n]+)/i', $text, $m ) ) { $redir = 1; $text = $m[1] . "\n"; # Remove all content but redirect @@ -894,7 +894,7 @@ class Article { else { $redir = 0; } $text = $this->preSaveTransform( $text ); - + # Update article, but only if changed. if( $wgDBtransactions ) { @@ -918,7 +918,7 @@ class Article { "WHERE cur_id=" . $this->getID() . " AND cur_timestamp='" . $this->getTimestamp() . "'"; $res = wfQuery( $sql, DB_WRITE, $fname ); - + if( wfAffectedRows() == 0 ) { /* Belated edit conflict! Run away!! */ return false; @@ -926,7 +926,7 @@ class Article { # This overwrites $oldtext if revision compression is on $flags = Article::compressRevisionText( $oldtext ); - + $oldtable=$wgIsPg?'"old"':'old'; if ($wgIsPg) { $oldtable='"old"'; @@ -956,7 +956,7 @@ class Article { $oldid = $wgIsPg?$old_id:wfInsertId( $res ); $bot = (int)($wgUser->isBot() || $forceBot); - RecentChange::notifyEdit( $now, $this->mTitle, $me2, $wgUser, $summary, + RecentChange::notifyEdit( $now, $this->mTitle, $me2, $wgUser, $summary, $oldid, $this->getTimestamp(), $bot ); Article::onArticleEdit( $this->mTitle ); } @@ -965,9 +965,9 @@ class Article { $sql = 'COMMIT'; wfQuery( $sql, DB_WRITE ); } - - if ($watchthis) { - if (!$this->mTitle->userIsWatching()) $this->watch(); + + if ($watchthis) { + if (!$this->mTitle->userIsWatching()) $this->watch(); } else { if ( $this->mTitle->userIsWatching() ) { $this->unwatch(); @@ -975,8 +975,8 @@ class Article { } # standard deferred updates $this->editUpdates( $text ); - - + + $urls = array(); # Template namespace # Purge all articles linking here @@ -989,7 +989,7 @@ class Article { } } } - + # Squid updates if ( $wgUseSquid ) { $urls = array_merge( $urls, $this->mTitle->getSquidURLs() ); @@ -1015,7 +1015,7 @@ class Article { $wgLinkCache->preFill( $this->mTitle ); $wgLinkCache->clear(); - # Now update the link cache by parsing the text + # Now update the link cache by parsing the text $wgOut = new OutputPage(); $wgOut->addWikiText( $text ); @@ -1092,17 +1092,17 @@ class Article { if ( $confirm ) { - $sql = "UPDATE cur SET cur_touched='" . wfTimestampNow() . "'," . - "cur_restrictions='{$limit}' WHERE cur_id={$id}"; - wfQuery( $sql, DB_WRITE, 'Article::protect' ); + $sql = "UPDATE cur SET cur_touched='" . wfTimestampNow() . "'," . + "cur_restrictions='{$limit}' WHERE cur_id={$id}"; + wfQuery( $sql, DB_WRITE, 'Article::protect' ); - $log = new LogPage( wfMsg( 'protectlogpage' ), wfMsg( 'protectlogtext' ) ); - if ( $limit === "" ) { - $log->addEntry( wfMsg( 'unprotectedarticle', $this->mTitle->getPrefixedText() ), $reason ); - } else { - $log->addEntry( wfMsg( 'protectedarticle', $this->mTitle->getPrefixedText() ), $reason ); - } - $wgOut->redirect( $this->mTitle->getFullURL() ); + $log = new LogPage( wfMsg( 'protectlogpage' ), wfMsg( 'protectlogtext' ) ); + if ( $limit === "" ) { + $log->addEntry( wfMsg( 'unprotectedarticle', $this->mTitle->getPrefixedText() ), $reason ); + } else { + $log->addEntry( wfMsg( 'protectedarticle', $this->mTitle->getPrefixedText() ), $reason ); + } + $wgOut->redirect( $this->mTitle->getFullURL() ); return; } else { $reason = htmlspecialchars( wfMsg( 'protectreason' ) ); @@ -1124,12 +1124,14 @@ class Article { $protcom = ''; if ( $limit === '' ) { + $wgOut->setPageTitle( wfMsg( 'confirmunprotect' ) ); $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->setPageTitle( wfMsg( 'confirmprotect' ) ); $wgOut->setSubtitle( wfMsg( 'protectsub', $sub ) ); $wgOut->addWikiText( wfMsg( 'confirmprotecttext' ) ); $check = htmlspecialchars( wfMsg( 'confirmprotect' ) ); @@ -1178,16 +1180,16 @@ class Article { return $this->protect( '' ); } - # UI entry point for page deletion + # UI entry point for page deletion function delete() { global $wgUser, $wgOut, $wgMessageCache, $wgRequest, $wgIsPg; $fname = 'Article::delete'; $confirm = $wgRequest->getBool( 'wpConfirm' ) && $wgRequest->wasPosted(); $reason = $wgRequest->getText( 'wpReason' ); - + # This code desperately needs to be totally rewritten - + # Check permissions if ( ( ! $wgUser->isSysop() ) ) { $wgOut->sysopRequired(); @@ -1241,19 +1243,19 @@ class Article { $text = Article::getRevisionText( $old ); $blanked = true; } - + } - - $length=strlen($text); - + + $length=strlen($text); + # 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 === '') { + if($length == 0 && $reason === '') { $reason = wfMsg('exblank'); } - + if($length < 500 && $reason === '') { - + # comment field=255, let's grep the first 150 to have some user # space left $text=substr($text,0,150); @@ -1268,27 +1270,27 @@ class Article { $reason=wfMsg('exbeforeblank') . " '".$text; } if($length>150) { $reason .= '...'; } # we've only pasted part of the text - $reason.="'"; + $reason.="'"; } } return $this->confirmDelete( '', $reason ); } - + # Output deletion confirmation dialog function confirmDelete( $par, $reason ) { global $wgOut; wfDebug( "Article::confirmDelete\n" ); - + $sub = htmlspecialchars( $this->mTitle->getPrefixedText() ); $wgOut->setSubtitle( wfMsg( 'deletesub', $sub ) ); $wgOut->setRobotpolicy( 'noindex,nofollow' ); $wgOut->addWikiText( wfMsg( 'confirmdeletetext' ) ); $formaction = $this->mTitle->escapeLocalURL( 'action=delete' . $par ); - + $confirm = htmlspecialchars( wfMsg( 'confirm' ) ); $check = htmlspecialchars( wfMsg( 'confirmcheck' ) ); $delcom = htmlspecialchars( wfMsg( 'deletecomment' ) ); @@ -1334,7 +1336,7 @@ class Article { $fname = 'Article::doDelete'; wfDebug( "$fname\n" ); - if ( $this->doDeleteArticle( $reason ) ) { + if ( $this->doDeleteArticle( $reason ) ) { $deleted = $this->mTitle->getPrefixedText(); $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) ); @@ -1375,14 +1377,14 @@ class Article { $u = new SiteStatsUpdate( 0, 1, -$this->isCountable( $this->getContent( true ) ) ); array_push( $wgDeferredUpdateList, $u ); - + $linksTo = $this->mTitle->getLinksTo(); # Squid purging if ( $wgUseSquid ) { - $urls = array( + $urls = array( $this->mTitle->getInternalURL(), - $this->mTitle->getInternalURL( 'history' ) + $this->mTitle->getInternalURL( 'history' ) ); foreach ( $linksTo as $linkTo ) { $urls[] = $linkTo->getInternalURL(); @@ -1420,7 +1422,7 @@ class Article { $sql = "DELETE FROM old WHERE old_namespace={$ns} AND " . "old_title='{$t}'"; wfQuery( $sql, DB_WRITE, $fname ); - + $sql = "DELETE FROM recentchanges WHERE rc_namespace={$ns} AND " . "rc_title='{$t}'"; wfQuery( $sql, DB_WRITE, $fname ); @@ -1429,7 +1431,7 @@ class Article { $t = wfStrencode( $this->mTitle->getPrefixedDBkey() ); Article::onArticleDelete( $this->mTitle ); - + $sql = 'INSERT INTO brokenlinks (bl_from,bl_to) VALUES '; $first = true; @@ -1437,7 +1439,7 @@ class Article { if ( ! $first ) { $sql .= ','; } $first = false; # Get article ID. Efficient because it was loaded into the cache by getLinksTo(). - $linkID = $titleObj->getArticleID(); + $linkID = $titleObj->getArticleID(); $sql .= "({$linkID},'{$t}')"; } if ( ! $first ) { @@ -1455,10 +1457,10 @@ class Article { $sql = "DELETE FROM brokenlinks WHERE bl_from={$id}"; wfQuery( $sql, DB_WRITE, $fname ); - + $sql = "DELETE FROM categorylinks WHERE cl_from={$id}"; wfQuery( $sql, DB_WRITE, $fname ); - + $log = new LogPage( wfMsg( 'dellogpage' ), wfMsg( 'dellogpagetext' ) ); $art = $this->mTitle->getPrefixedText(); $log->addEntry( wfMsg( 'deletedarticle', $art ), $reason ); @@ -1481,14 +1483,14 @@ class Article { $wgOut->readOnlyPage( $this->getContent( true ) ); return; } - + # Enhanced rollback, marks edits rc_bot=1 $bot = $wgRequest->getBool( 'bot' ); - + # Replace all this user's current edits with the next one down $tt = wfStrencode( $this->mTitle->getDBKey() ); $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}"; @@ -1502,7 +1504,7 @@ class Article { $ut = wfStrencode( $s->cur_user_text ); $uid = $s->cur_user; $pid = $s->cur_id; - + $from = str_replace( '_', ' ', $wgRequest->getVal( 'from' ) ); if( $from != $s->cur_user_text ) { $wgOut->setPageTitle(wfmsg('rollbackfailed')); @@ -1517,7 +1519,7 @@ class Article { } return; } - + # Get the last edit not by this guy $use_index=$wgIsMySQL?"USE INDEX (name_title_timestamp)":""; @@ -1535,7 +1537,7 @@ class Article { return; } $s = wfFetchObject( $res ); - + if ( $bot ) { # Mark all reverted edits as bot $sql = 'UPDATE recentchanges SET rc_bot=1 WHERE ' . @@ -1552,7 +1554,7 @@ class Article { Article::onArticleEdit( $this->mTitle ); $wgOut->returnToMain( false ); } - + # Do standard deferred updates after page view @@ -1589,7 +1591,7 @@ class Article { $id = $this->getID(); $title = $this->mTitle->getPrefixedDBkey(); $shortTitle = $this->mTitle->getDBkey(); - + $adj = $this->mCountAdjustment; if ( 0 != $id ) { @@ -1626,7 +1628,7 @@ class Article { global $wgParser, $wgUser; return $wgParser->preSaveTransform( $text, $this->mTitle, $wgUser, ParserOptions::newFromUser( $wgUser ) ); } - + /* Caching functions */ # checkLastModified returns true if it has taken care of all @@ -1653,7 +1655,7 @@ class Article { $cache->loadFromFileCache(); return true; } else { - wfDebug( " tryFileCache() - starting buffer\n" ); + wfDebug( " tryFileCache() - starting buffer\n" ); ob_start( array(&$cache, 'saveToFileCache' ) ); } } else { @@ -1664,7 +1666,7 @@ class Article { function isFileCacheable() { global $wgUser, $wgUseFileCache, $wgShowIPinHeader, $wgRequest; extract( $wgRequest->getValues( 'action', 'oldid', 'diff', 'redirect', 'printable' ) ); - + return $wgUseFileCache and (!$wgShowIPinHeader) and ($this->getID() != 0) @@ -1678,7 +1680,7 @@ class Article { and (!isset($printable)) and (!$this->mRedirectedFrom); } - + # Loads cur_touched and returns a value indicating if it should be used function checkTouched() { $id = $this->getID(); @@ -1702,14 +1704,14 @@ class Article { $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(); @@ -1746,14 +1748,14 @@ class Article { $id = intval( $id ); global $wgHitcounterUpdateFreq; - if( $wgHitcounterUpdateFreq <= 1 ){ // + if( $wgHitcounterUpdateFreq <= 1 ){ // wfQuery('UPDATE cur SET cur_counter = cur_counter + 1 ' . 'WHERE cur_id = '.$id, DB_WRITE); return; } # Not important enough to warrant an error page in case of failure - $oldignore = wfIgnoreSQLErrors( true ); + $oldignore = wfIgnoreSQLErrors( true ); wfQuery("INSERT INTO hitcounter (hc_id) VALUES ({$id})", DB_WRITE); @@ -1767,7 +1769,7 @@ class Article { $res = wfQuery('SELECT COUNT(*) as n FROM hitcounter', DB_WRITE); $row = wfFetchObject( $res ); $rown = intval( $row->n ); - if( $rown >= $wgHitcounterUpdateFreq ){ + if( $rown >= $wgHitcounterUpdateFreq ){ wfProfileIn( 'Article::incViewCount-collect' ); $old_user_abort = ignore_user_abort( true ); @@ -1788,18 +1790,18 @@ class Article { } # The onArticle*() functions are supposed to be a kind of hooks - # which should be called whenever any of the specified actions - # are done. + # which should be called whenever any of the specified actions + # are done. # - # This is a good place to put code to clear caches, for instance. + # This is a good place to put code to clear caches, for instance. - # This is called on page move and undelete, as well as edit + # This is called on page move and undelete, as well as edit /* static */ function onArticleCreate($title_obj){ global $wgUseSquid, $wgDeferredUpdateList; $titles = $title_obj->getBrokenLinksTo(); - - # Purge squid + + # Purge squid if ( $wgUseSquid ) { $urls = $title_obj->getSquidURLs(); foreach ( $titles as $linkTitle ) { @@ -1820,6 +1822,76 @@ class Article { /* static */ function onArticleEdit($title_obj){ LinkCache::linksccClearPage( $title_obj->getArticleID() ); } + + # Info about this page + + function info() + { + global $wgUser, $wgTitle, $wgOut, $wgLang; + + $basenamespace = $wgTitle->getNamespace() & (~1); + $cur_clause = "cur_title='".$wgTitle->getDBkey()."' AND cur_namespace=".$basenamespace; + $old_clause = "old_title='".$wgTitle->getDBkey()."' AND old_namespace=".$basenamespace; + $wl_clause = "wl_title='".$wgTitle->getDBkey()."' AND wl_namespace=".$basenamespace; + $fullTitle = $wgTitle->makeName($basenamespace, $wgTitle->getDBKey()); + $wgOut->setPagetitle( $fullTitle ); + $wgOut->setSubtitle( wfMsg( "infosubtitle" )); + + # first, see if the page exists at all. + $sql = "SELECT COUNT(*) FROM cur WHERE ".$cur_clause; + $exists = wfSingleQuery( $sql , DB_READ ); + if ($exists < 1) { + $wgOut->addHTML( wfMsg("noarticletext") ); + } else { + $sql = "SELECT COUNT(*) FROM watchlist WHERE ".$wl_clause; + $wgOut->addHTML( "
  • " . wfMsg("numwatchers") . wfSingleQuery( $sql, DB_READ ) . "
  • " ); + $sql = "SELECT COUNT(*) FROM old WHERE ".$old_clause; + $old = wfSingleQuery( $sql, DB_READ ); + $wgOut->addHTML( "
  • " . wfMsg("numedits") . ($old + 1) . "
  • "); + + # to find number of distinct authors, we need to do some + # funny stuff because of the cur/old table split: + # - first, find the name of the 'cur' author + # - then, find the number of *other* authors in 'old' + + # find 'cur' author + $sql = "SELECT cur_user_text FROM cur WHERE ".$cur_clause; + $cur_author = wfSingleQuery( $sql, DB_READ ); + + # find number of 'old' authors excluding 'cur' author + $sql = "SELECT COUNT(DISTINCT old_user_text) FROM old WHERE ".$old_clause + ." AND old_user_text<>'" . $cur_author . "'"; + $authors = wfSingleQuery( $sql, DB_READ ) + 1; + + # now for the Talk page ... + $cur_clause = "cur_title='".$wgTitle->getDBkey()."' AND cur_namespace=".($basenamespace+1); + $old_clause = "old_title='".$wgTitle->getDBkey()."' AND old_namespace=".($basenamespace+1); + + # does it exist? + $sql = "SELECT COUNT(*) FROM cur WHERE ".$cur_clause; + $exists = wfSingleQuery( $sql , DB_READ ); + + # number of edits + if ($exists > 0) { + $sql = "SELECT COUNT(*) FROM old WHERE ".$old_clause; + $old = wfSingleQuery( $sql, DB_READ ); + $wgOut->addHTML( "
  • " . wfMsg("numtalkedits") . ($old + 1) . "
  • "); + } + $wgOut->addHTML( "
  • " . wfMsg("numauthors") . $authors . "
  • " ); + + # number of authors + if ($exists > 0) { + $sql = "SELECT cur_user_text FROM cur WHERE ".$cur_clause; + $cur_author = wfSingleQuery( $sql, DB_READ ); + + $sql = "SELECT COUNT(DISTINCT old_user_text) FROM old WHERE " + .$old_clause." AND old_user_text<>'" . $cur_author . "'"; + $authors = wfSingleQuery( $sql, DB_READ ) + 1; + + $wgOut->addHTML( "
  • " . wfMsg("numtalkauthors") . $authors . "
" ); + } + } + } } ?> diff --git a/includes/DatabaseFunctions.php b/includes/DatabaseFunctions.php index 0169b9ff5e..3fde31b9f0 100644 --- a/includes/DatabaseFunctions.php +++ b/includes/DatabaseFunctions.php @@ -39,6 +39,15 @@ function wfQuery( $sql, $db, $fname = "" ) } } +function wfSingleQuery( $sql, $db, $fname = "" ) +{ + $res = wfQuery($sql, $db, $fname ); + $row = wfFetchRow( $res ); + $ret = $row[0]; + wfFreeResult( $res ); + return $ret; +} + function &wfGetDB( $db = DB_LAST ) { global $wgLoadBalancer; diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 50d0d38bfe..8007bfb55f 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -14,19 +14,19 @@ class OutputPage { var $mSuppressQuickbar; var $mOnloadHandler; var $mDoNothing; - var $mContainsOldMagic, $mContainsNewMagic; + var $mContainsOldMagic, $mContainsNewMagic; var $mIsArticleRelated; var $mParserOptions; var $mShowFeedLinks = false; var $mEnableClientCache = true; - + function OutputPage() { $this->mHeaders = $this->mCookies = $this->mMetatags = $this->mKeywords = $this->mLinktags = array(); $this->mHTMLtitle = $this->mPagetitle = $this->mBodytext = $this->mRedirect = $this->mLastModified = - $this->mSubtitle = $this->mDebugtext = $this->mRobotpolicy = + $this->mSubtitle = $this->mDebugtext = $this->mRobotpolicy = $this->mOnloadHandler = ""; $this->mIsArticleRelated = $this->mIsarticle = $this->mPrintable = true; $this->mSuppressQuickbar = $this->mPrintable = false; @@ -48,7 +48,7 @@ class OutputPage { function addKeyword( $text ) { array_push( $this->mKeywords, $text ); } function addScript( $script ) { $this->mScripts .= $script; } function getScript() { return $this->mScripts; } - + function addLink( $linkarr ) { # $linkarr should be an associative array of attributes. We'll escape on output. array_push( $this->mLinktags, $linkarr ); @@ -65,7 +65,7 @@ class OutputPage { # 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. + # returns true iff cache-ok headers was sent. function checkLastModified ( $timestamp ) { global $wgLang, $wgCachePages, $wgUser; @@ -92,7 +92,7 @@ class OutputPage { $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 ); + wfDebug( "-- we might send Last-Modified : $lastmod\n", false ); if( ($ismodsince >= $timestamp ) and $wgUser->validateCache( $ismodsince ) ) { # Make sure you're in a place you can leave when you call us! @@ -116,11 +116,11 @@ class OutputPage { global $action; switch($action) { case 'edit': - return wfMsg('edit'); + return wfMsg('edit'); case 'history': return wfMsg('history_short'); case 'protect': - return wfMsg('unprotect'); + return wfMsg('protect'); case 'unprotect': return wfMsg('unprotect'); case 'delete': @@ -131,6 +131,8 @@ class OutputPage { return wfMsg('unwatch'); case 'submit': return wfMsg('preview'); + case 'info': + return wfMsg('info_short'); default: return ''; } @@ -168,8 +170,8 @@ class OutputPage { $this->mIsarticle = false; } } - function setArticleFlag( $v ) { - $this->mIsarticle = $v; + function setArticleFlag( $v ) { + $this->mIsarticle = $v; if ( $v ) { $this->mIsArticleRelated = $v; } @@ -179,7 +181,7 @@ class OutputPage { { return $this->mIsArticleRelated; } - + function getLanguageLinks() { return $this->mLanguageLinks; } @@ -191,7 +193,7 @@ class OutputPage { } function getCategoryLinks() { return $this->mCategoryLinks; - } + } function addCategoryLinks($newLinkArray) { $this->mCategoryLinks += $newLinkArray; } @@ -218,12 +220,12 @@ class OutputPage { function addWikiText( $text, $linestart = true, $cacheArticle = NULL ) { global $wgParser, $wgParserCache, $wgUser, $wgTitle; - + $parserOutput = $wgParser->parse( $text, $wgTitle, $this->mParserOptions, $linestart ); if ( $cacheArticle ) { $wgParserCache->save( $parserOutput, $cacheArticle, $wgUser ); } - + $this->mLanguageLinks += $parserOutput->getLanguageLinks(); $this->mCategoryLinks += $parserOutput->getCategoryLinks(); $this->addHTML( $parserOutput->getText() ); @@ -241,24 +243,24 @@ class OutputPage { return false; } } - + # Set the maximum cache time on the Squid in seconds function setSquidMaxage( $maxage ) { $this->mSquidMaxage = $maxage; } - + # Use enableClientCache(false) to force it to send nocache headers function enableClientCache( $state ) { return wfSetVar( $this->mEnableClientCache, $state ); } - + function sendCacheControl() { global $wgUseSquid, $wgUseESI; # FIXME: This header may cause trouble with some versions of Internet Explorer header( "Vary: Accept-Encoding, Cookie" ); if( $this->mEnableClientCache ) { - if( $wgUseSquid && ! isset( $_COOKIE[ini_get( "session.name") ] ) && - ! $this->isPrintable() && $this->mSquidMaxage != 0 ) + if( $wgUseSquid && ! isset( $_COOKIE[ini_get( "session.name") ] ) && + ! $this->isPrintable() && $this->mSquidMaxage != 0 ) { if ( $wgUseESI ) { # We'll purge the proxy cache explicitly, but require end user agents @@ -272,7 +274,7 @@ class OutputPage { } else { # We'll purge the proxy cache for anons explicitly, but require end user agents # to revalidate against the proxy on each visit. - # IMPORTANT! The Squid needs to replace the Cache-Control header with + # IMPORTANT! The Squid needs to replace the Cache-Control header with # Cache-Control: s-maxage=0, must-revalidate, max-age=0 wfDebug( "** local proxy caching; {$this->mLastModified} **\n", false ); # start with a shorter timeout for initial testing @@ -297,7 +299,7 @@ class OutputPage { header( "Pragma: no-cache" ); } } - + # Finally, all the text has been munged and accumulated into # the object, let's actually output it: # @@ -311,7 +313,7 @@ class OutputPage { } $fname = "OutputPage::output"; wfProfileIn( $fname ); - + $sk = $wgUser->getSkin(); if ( "" != $this->mRedirect ) { @@ -326,9 +328,9 @@ class OutputPage { } $this->mLastModified = gmdate( "D, j M Y H:i:s" ) . " GMT"; } - + $this->sendCacheControl(); - + if( $wgDebugRedirects ) { $url = htmlspecialchars( $this->mRedirect ); print "\n\nRedirect\n\n\n"; @@ -339,10 +341,10 @@ class OutputPage { } return; } - - + + $this->sendCacheControl(); - + header( "Content-type: $wgMimeType; charset={$wgOutputEncoding}" ); header( "Content-language: {$wgLanguageCode}" ); @@ -350,7 +352,7 @@ class OutputPage { foreach( $this->mCookies as $name => $val ) { setcookie( $name, $val, $exp, "/" ); } - + $sk->outputPage( $this ); # flush(); } @@ -373,7 +375,7 @@ class OutputPage { global $wgUser, $wgLang; $wgInputEncoding = strtolower( $wgInputEncoding ); - + if( $wgUser->getOption( 'altencoding' ) ) { $wgLang->setAltEncoding(); return; @@ -383,11 +385,11 @@ class OutputPage { $wgOutputEncoding = strtolower( $wgOutputEncoding ); return; } - + /* # This code is unused anyway! # Commenting out. --bv 2003-11-15 - + $a = explode( ",", $_SERVER['HTTP_ACCEPT_CHARSET'] ); $best = 0.0; $bestset = "*"; @@ -415,7 +417,7 @@ class OutputPage { $wgOutputEncoding = $wgInputEncoding; } - # Returns a HTML comment with the elapsed time since request. + # Returns a HTML comment with the elapsed time since request. # This method has no side effects. function reportTime() { @@ -425,7 +427,7 @@ class OutputPage { list( $usec, $sec ) = explode( " ", $wgRequestTime ); $start = (float)$sec + (float)$usec; $elapsed = $now - $start; - + # Use real server name if available, so we know which machine # in a server farm generated the current page. if ( function_exists( "posix_uname" ) ) { @@ -477,7 +479,7 @@ class OutputPage { $this->mBodytext = ""; $sk = $wgUser->getSkin(); - $ap = $sk->makeKnownLink( wfMsg( "administrators" ), "" ); + $ap = $sk->makeKnownLink( wfMsg( "administrators" ), "" ); $this->addHTML( wfMsg( "sysoptext", $ap ) ); $this->returnToMain(); } @@ -493,7 +495,7 @@ class OutputPage { $this->mBodytext = ""; $sk = $wgUser->getSkin(); - $ap = $sk->makeKnownLink( wfMsg( "administrators" ), "" ); + $ap = $sk->makeKnownLink( wfMsg( "administrators" ), "" ); $this->addHTML( wfMsg( "developertext", $ap ) ); $this->returnToMain(); } @@ -511,9 +513,9 @@ class OutputPage { # We put a comment in the .html file so a Sysop can diagnose the page the # user can't see. - $this->addHTML( "\n" ); $this->returnToMain(); # Flip back to the main page after 10 seconds. } @@ -537,7 +539,7 @@ class OutputPage { $msg = str_replace( "$2", htmlspecialchars( $fname ), $msg ); $msg = str_replace( "$3", $errno, $msg ); $msg = str_replace( "$4", htmlspecialchars( $error ), $msg ); - + if ( $wgCommandLineMode || !is_object( $wgUser )) { print "$msg\n"; wfAbruptExit(); @@ -566,7 +568,7 @@ class OutputPage { $reason = file_get_contents( $wgReadOnlyFile ); $this->addWikiText( wfMsg( "readonlytext", $reason ) ); } - + if( is_string( $source ) ) { if( strcmp( $source, "" ) == 0 ) { $source = wfMsg( "noarticletext" ); @@ -577,7 +579,7 @@ class OutputPage { htmlspecialchars( $source ) . "\n"; $this->addHTML( $text ); } - + $this->returnToMain( false ); } @@ -624,7 +626,7 @@ class OutputPage { function returnToMain( $auto = true, $returnto = NULL ) { global $wgUser, $wgOut, $wgRequest; - + if ( $returnto == NULL ) { $returnto = $wgRequest->getText( 'returnto' ); } @@ -658,7 +660,7 @@ class OutputPage { "/[_]/" => ' ' ); $a = htmlspecialchars(preg_replace(array_keys($strip), array_values($strip),$a )); - + $wgOut->addMeta ( "KEYWORDS" , $a ) ; } @@ -673,7 +675,7 @@ class OutputPage { } else { $ret = ""; } - + $ret .= "\n"; if ( "" == $this->mHTMLtitle ) { @@ -688,7 +690,7 @@ class OutputPage { $ret .= "\n"; $ret .= "\n" . htmlspecialchars( $this->mHTMLtitle ) . "\n"; array_push( $this->mMetatags, array( "http:Content-type", "$wgMimeType; charset={$wgOutputEncoding}" ) ); - + $ret .= $this->getHeadLinks(); global $wgStylePath; if( $this->isPrintable() ) { @@ -707,7 +709,7 @@ class OutputPage { $ret .= "\n"; return $ret; } - + function getHeadLinks() { global $wgRequest, $wgStylePath; $ret = "";