X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FArticle.php;h=9e12611c13dd64152efedb3cc4a1addc2d1e2483;hb=8485b649c605bc4e785f8eacc359855c297b0fdb;hp=c469888d3f23bf35c85a5fef6dfcc692a068b754;hpb=fa239349f2d5d4456c45efae16d1673d6472e165;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Article.php b/includes/Article.php index c469888d3f..9e12611c13 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -1,7 +1,6 @@ mTitle =& $title; $this->mOldId = $oldId; $this->clear(); } - + /** * Tell the page view functions that this view was redirected * from another page on the wiki. @@ -57,14 +55,14 @@ class Article { function setRedirectedFrom( $from ) { $this->mRedirectedFrom = $from; } - + /** * @return mixed false, Title of in-wiki target, or string with URL */ function followRedirect() { $text = $this->getContent(); $rt = Title::newFromRedirect( $text ); - + # process if title object is valid and not special:userlogout if( $rt ) { if( $rt->getInterwiki() != '' ) { @@ -73,18 +71,18 @@ class Article { // // This can be hard to reverse and may produce loops, // so they may be disabled in the site configuration. - + $source = $this->mTitle->getFullURL( 'redirect=no' ); return $rt->getFullURL( 'rdfrom=' . urlencode( $source ) ); } } else { if( $rt->getNamespace() == NS_SPECIAL ) { - // Gotta hand redirects to special pages differently: + // Gotta handle redirects to special pages differently: // Fill the HTTP response "Location" header and ignore // the rest of the page we're on. // // This can be hard to reverse, so they may be disabled. - + if( $rt->isSpecial( 'Userlogout' ) ) { // rolleyes } else { @@ -94,7 +92,7 @@ class Article { return $rt; } } - + // No or invalid redirect return false; } @@ -139,7 +137,7 @@ class Article { * @return Return the text of this revision */ function getContent() { - global $wgRequest, $wgUser, $wgOut; + global $wgUser, $wgOut; wfProfileIn( __METHOD__ ); @@ -236,9 +234,6 @@ class Article { # Pre-fill content with error message so that if something # fails we'll have something telling us what we intended. - - $t = $this->mTitle->getPrefixedText(); - $this->mOldId = $oldid; $this->fetchContent( $oldid ); } @@ -250,7 +245,7 @@ class Article { * @param array $conditions * @private */ - function pageData( &$dbr, $conditions ) { + function pageData( $dbr, $conditions ) { $fields = array( 'page_id', 'page_namespace', @@ -276,7 +271,7 @@ class Article { * @param Database $dbr * @param Title $title */ - function pageDataFromTitle( &$dbr, $title ) { + function pageDataFromTitle( $dbr, $title ) { return $this->pageData( $dbr, array( 'page_namespace' => $title->getNamespace(), 'page_title' => $title->getDBkey() ) ); @@ -286,7 +281,7 @@ class Article { * @param Database $dbr * @param int $id */ - function pageDataFromId( &$dbr, $id ) { + function pageDataFromId( $dbr, $id ) { return $this->pageData( $dbr, array( 'page_id' => $id ) ); } @@ -299,17 +294,18 @@ class Article { */ function loadPageData( $data = 'fromdb' ) { if ( $data === 'fromdb' ) { - $dbr =& $this->getDB(); + $dbr = $this->getDB(); $data = $this->pageDataFromId( $dbr, $this->getId() ); } - + $lc =& LinkCache::singleton(); if ( $data ) { $lc->addGoodLinkObj( $data->page_id, $this->mTitle ); $this->mTitle->mArticleID = $data->page_id; + + # Old-fashioned restrictions. $this->mTitle->loadRestrictions( $data->page_restrictions ); - $this->mTitle->mRestrictionsLoaded = true; $this->mCounter = $data->page_counter; $this->mTouched = wfTimestamp( TS_MW, $data->page_touched ); @@ -336,7 +332,7 @@ class Article { return $this->mContent; } - $dbr =& $this->getDB(); + $dbr = $this->getDB(); # Pre-fill content with error message so that if something # fails we'll have something telling us what we intended. @@ -408,9 +404,8 @@ class Article { * * @return Database */ - function &getDB() { - $ret =& wfGetDB( DB_MASTER ); - return $ret; + function getDB() { + return wfGetDB( DB_MASTER ); } /** @@ -458,7 +453,7 @@ class Article { if ( $id == 0 ) { $this->mCounter = 0; } else { - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $this->mCounter = $dbr->selectField( 'page', 'page_counter', array( 'page_id' => $id ), 'Article::getCount', $this->getSelectOptions() ); } @@ -474,12 +469,12 @@ class Article { * @return bool */ function isCountable( $text ) { - global $wgUseCommaCount, $wgContentNamespaces; + global $wgUseCommaCount; $token = $wgUseCommaCount ? ',' : '[['; return - array_search( $this->mTitle->getNamespace(), $wgContentNamespaces ) !== false - && ! $this->isRedirect( $text ) + $this->mTitle->isContentPage() + && !$this->isRedirect( $text ) && in_string( $token, $text ); } @@ -575,13 +570,10 @@ class Article { function getContributors($limit = 0, $offset = 0) { # XXX: this is expensive; cache this info somewhere. - $title = $this->mTitle; $contribs = array(); - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $revTable = $dbr->tableName( 'revision' ); $userTable = $dbr->tableName( 'user' ); - $encDBkey = $dbr->addQuotes( $title->getDBkey() ); - $ns = $title->getNamespace(); $user = $this->getUser(); $pageId = $this->getId(); @@ -613,12 +605,13 @@ class Article { global $wgUser, $wgOut, $wgRequest, $wgContLang; global $wgEnableParserCache, $wgStylePath, $wgUseRCPatrol, $wgParser; global $wgUseTrackbacks, $wgNamespaceRobotPolicies; + $sk = $wgUser->getSkin(); wfProfileIn( __METHOD__ ); $parserCache =& ParserCache::singleton(); $ns = $this->mTitle->getNamespace(); # shortcut - + # Get variables from query string $oldid = $this->getOldID(); @@ -632,14 +625,21 @@ class Article { $diff = $wgRequest->getVal( 'diff' ); $rcid = $wgRequest->getVal( 'rcid' ); $rdfrom = $wgRequest->getVal( 'rdfrom' ); + $diffOnly = $wgRequest->getBool( 'diffonly', $wgUser->getOption( 'diffonly' ) ); $wgOut->setArticleFlag( true ); - if ( isset( $wgNamespaceRobotPolicies[$ns] ) ) { + + # Discourage indexing of printable versions, but encourage following + if( $wgOut->isPrintable() ) { + $policy = 'noindex,follow'; + } elseif( isset( $wgNamespaceRobotPolicies[$ns] ) ) { + # Honour customised robot policies for this namespace $policy = $wgNamespaceRobotPolicies[$ns]; } else { + # Default to encourage indexing and following links $policy = 'index,follow'; } - $wgOut->setRobotpolicy( $policy ); + $wgOut->setRobotPolicy( $policy ); # If we got diff and oldid in the query, we want to see a # diff page instead of the article. @@ -650,8 +650,8 @@ class Article { $de = new DifferenceEngine( $this->mTitle, $oldid, $diff, $rcid ); // DifferenceEngine directly fetched the revision: $this->mRevIdFetched = $de->mNewid; - $de->showDiffPage(); - + $de->showDiffPage( $diffOnly ); + // Needed to get the page's current revision $this->loadPageData(); if( $diff == 0 || $diff == $this->mLatest ) { @@ -661,7 +661,7 @@ class Article { wfProfileOut( __METHOD__ ); return; } - + if ( empty( $oldid ) && $this->checkTouched() ) { $wgOut->setETag($parserCache->getETag($this, $wgUser)); @@ -692,9 +692,16 @@ class Article { // This is an internally redirected page view. // We'll need a backlink to the source page for navigation. if ( wfRunHooks( 'ArticleViewRedirect', array( &$this ) ) ) { - $redir = Linker::makeKnownLinkObj( $this->mRedirectedFrom, '', 'redirect=no' ); + $sk = $wgUser->getSkin(); + $redir = $sk->makeKnownLinkObj( $this->mRedirectedFrom, '', 'redirect=no' ); $s = wfMsg( 'redirectedfrom', $redir ); $wgOut->setSubtitle( $s ); + + // Set the fragment if one was specified in the redirect + if ( strval( $this->mTitle->getFragment() ) != '' ) { + $fragment = Xml::escapeJsString( $this->mTitle->getFragmentForURL() ); + $wgOut->addInlineScript( "redirectToFragment(\"$fragment\");" ); + } $wasRedirected = true; } } elseif ( !empty( $rdfrom ) ) { @@ -702,17 +709,18 @@ class Article { // If it was reported from a trusted site, supply a backlink. global $wgRedirectSources; if( $wgRedirectSources && preg_match( $wgRedirectSources, $rdfrom ) ) { - $redir = Linker::makeExternalLink( $rdfrom, $rdfrom ); + $sk = $wgUser->getSkin(); + $redir = $sk->makeExternalLink( $rdfrom, $rdfrom ); $s = wfMsg( 'redirectedfrom', $redir ); $wgOut->setSubtitle( $s ); $wasRedirected = true; } } - + $outputDone = false; + wfRunHooks( 'ArticleViewHeader', array( &$this ) ); if ( $pcache ) { if ( $wgOut->tryParserCache( $this, $wgUser ) ) { - wfRunHooks( 'ArticleViewHeader', array( &$this ) ); $outputDone = true; } } @@ -759,11 +767,6 @@ class Article { } } if( !$outputDone ) { - /** - * @fixme: this hook doesn't work most of the time, as it doesn't - * trigger when the parser cache is used. - */ - wfRunHooks( 'ArticleViewHeader', array( &$this ) ) ; $wgOut->setRevisionId( $this->getRevIdFetched() ); # 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 @@ -781,19 +784,16 @@ class Article { if( !$wasRedirected && $this->isCurrent() ) { $wgOut->setSubtitle( wfMsgHtml( 'redirectpagesub' ) ); } - $targetUrl = $rt->escapeLocalURL(); - # fixme unused $titleText : - $titleText = htmlspecialchars( $rt->getPrefixedText() ); - $link = Linker::makeLinkObj( $rt ); + $link = $sk->makeLinkObj( $rt, $rt->getFullText() ); - $wgOut->addHTML( '#REDIRECT' . + $wgOut->addHTML( '#REDIRECT ' . ''.$link.'' ); $parseout = $wgParser->parse($text, $this->mTitle, ParserOptions::newFromUser($wgUser)); $wgOut->addParserOutputNoText( $parseout ); } else if ( $pcache ) { # Display content and save to parser cache - $wgOut->addPrimaryWikiText( $text, $this ); + $this->outputWikiText( $text ); } else { # Display content, don't attempt to save to parser cache # Don't show section-edit links on old revisions... this way lies madness. @@ -801,11 +801,21 @@ class Article { $oldEditSectionSetting = $wgOut->parserOptions()->setEditSection( false ); } # Display content and don't save to parser cache - $wgOut->addPrimaryWikiText( $text, $this, false ); + # With timing hack -- TS 2006-07-26 + $time = -wfTime(); + $this->outputWikiText( $text, false ); + $time += wfTime(); + + # Timing hack + if ( $time > 3 ) { + wfDebugLog( 'slow-parse', sprintf( "%-5.2f %s", $time, + $this->mTitle->getPrefixedDBkey())); + } if( !$this->isCurrent() ) { $wgOut->parserOptions()->setEditSection( $oldEditSectionSetting ); } + } } /* title may have been set from the cache */ @@ -825,8 +835,9 @@ class Article { if ( $wgUseRCPatrol && !is_null( $rcid ) && $rcid != 0 && $wgUser->isAllowed( 'patrol' ) ) { $wgOut->addHTML( "' ); @@ -843,7 +854,7 @@ class Article { function addTrackbacks() { global $wgOut, $wgUser; - $dbr =& wfGetDB(DB_SLAVE); + $dbr = wfGetDB(DB_SLAVE); $tbs = $dbr->select( /* FROM */ 'trackbacks', /* SELECT */ array('tb_id', 'tb_title', 'tb_url', 'tb_ex', 'tb_name'), @@ -889,7 +900,7 @@ class Article { return; } - $db =& wfGetDB(DB_MASTER); + $db = wfGetDB(DB_MASTER); $db->delete('trackbacks', array('tb_id' => $wgRequest->getInt('tbid'))); $wgTitle->invalidateCache(); $wgOut->addWikiText(wfMsg('trackbackdeleteok')); @@ -908,7 +919,7 @@ class Article { function purge() { global $wgUser, $wgRequest, $wgOut; - if ( $wgUser->isLoggedIn() || $wgRequest->wasPosted() ) { + if ( $wgUser->isAllowed( 'purge' ) || $wgRequest->wasPosted() ) { if( wfRunHooks( 'ArticlePurge', array( &$this ) ) ) { $this->doPurge(); } @@ -926,7 +937,7 @@ class Article { $wgOut->addHTML( $msg ); } } - + /** * Perform the actions of a page purging */ @@ -955,11 +966,10 @@ class Article { * Best if all done inside a transaction. * * @param Database $dbw - * @param string $restrictions * @return int The newly created page_id key * @private */ - function insertOn( &$dbw, $restrictions = '' ) { + function insertOn( $dbw ) { wfProfileIn( __METHOD__ ); $page_id = $dbw->nextSequenceValue( 'page_page_id_seq' ); @@ -968,7 +978,7 @@ class Article { 'page_namespace' => $this->mTitle->getNamespace(), 'page_title' => $this->mTitle->getDBkey(), 'page_counter' => 0, - 'page_restrictions' => $restrictions, + 'page_restrictions' => '', 'page_is_redirect' => 0, # Will set this shortly... 'page_is_new' => 1, 'page_random' => wfRandom(), @@ -994,7 +1004,7 @@ class Article { * when different from the currently set value. * Giving 0 indicates the new page flag should * be set on. - * @param bool $lastRevIsRedirect If given, will optimize adding and + * @param bool $lastRevIsRedirect If given, will optimize adding and * removing rows in redirect table. * @return bool true on success, false on failure * @private @@ -1004,7 +1014,7 @@ class Article { $text = $revision->getText(); $rt = Title::newFromRedirect( $text ); - + $conditions = array( 'page_id' => $this->getId() ); if( !is_null( $lastRevision ) ) { # An extra check against threads stepping on each other @@ -1026,20 +1036,20 @@ class Article { if ($result) { // FIXME: Should the result from updateRedirectOn() be returned instead? - $this->updateRedirectOn( $dbw, $rt, $lastRevIsRedirect ); + $this->updateRedirectOn( $dbw, $rt, $lastRevIsRedirect ); } - + wfProfileOut( __METHOD__ ); return $result; } /** - * Add row to the redirect table if this is a redirect, remove otherwise. + * Add row to the redirect table if this is a redirect, remove otherwise. * * @param Database $dbw * @param $redirectTitle a title object pointing to the redirect target, - * or NULL if this is not a redirect - * @param bool $lastRevIsRedirect If given, will optimize adding and + * or NULL if this is not a redirect + * @param bool $lastRevIsRedirect If given, will optimize adding and * removing rows in redirect table. * @return bool true on success, false on failure * @private @@ -1065,7 +1075,7 @@ class Article { $dbw->replace( 'redirect', array( 'rd_from' ), $set, __METHOD__ ); } else { - // This is not a redirect, remove row from redirect table + // This is not a redirect, remove row from redirect table $where = array( 'rd_from' => $this->getId() ); $dbw->delete( 'redirect', $where, __METHOD__); } @@ -1073,7 +1083,7 @@ class Article { wfProfileOut( __METHOD__ ); return ( $dbw->affectedRows() != 0 ); } - + return true; } @@ -1117,14 +1127,14 @@ class Article { */ function replaceSection($section, $text, $summary = '', $edittime = NULL) { wfProfileIn( __METHOD__ ); - + if( $section == '' ) { // Whole-page edit; let the text through unmolested. } else { if( is_null( $edittime ) ) { $rev = Revision::newFromTitle( $this->mTitle ); } else { - $dbw =& wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER ); $rev = Revision::loadFromTimestamp( $dbw, $this->mTitle, $edittime ); } if( is_null( $rev ) ) { @@ -1134,13 +1144,18 @@ class Article { } $oldtext = $rev->getText(); - if($section=='new') { - if($summary) $subject="== {$summary} ==\n\n"; - $text=$oldtext."\n\n".$subject.$text; + if( $section == 'new' ) { + # Inserting a new section + $subject = $summary ? "== {$summary} ==\n\n" : ''; + $text = strlen( trim( $oldtext ) ) > 0 + ? "{$oldtext}\n\n{$subject}{$text}" + : "{$subject}{$text}"; } else { + # Replacing an existing section; roll out the big guns global $wgParser; $text = $wgParser->replaceSection( $oldtext, $section, $text ); } + } wfProfileOut( __METHOD__ ); @@ -1151,7 +1166,7 @@ class Article { * @deprecated use Article::doEdit() */ function insertNewArticle( $text, $summary, $isminor, $watchthis, $suppressRC=false, $comment=false ) { - $flags = EDIT_NEW | EDIT_DEFER_UPDATES | + $flags = EDIT_NEW | EDIT_DEFER_UPDATES | EDIT_AUTOSUMMARY | ( $isminor ? EDIT_MINOR : 0 ) | ( $suppressRC ? EDIT_SUPPRESS_RC : 0 ); @@ -1159,10 +1174,10 @@ class Article { if ( $comment && $summary != "" ) { $text = "== {$summary} ==\n\n".$text; } - + $this->doEdit( $text, $summary, $flags ); - $dbw =& wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER ); if ($watchthis) { if (!$this->mTitle->userIsWatching()) { $dbw->begin(); @@ -1183,13 +1198,13 @@ class Article { * @deprecated use Article::doEdit() */ function updateArticle( $text, $summary, $minor, $watchthis, $forceBot = false, $sectionanchor = '' ) { - $flags = EDIT_UPDATE | EDIT_DEFER_UPDATES | + $flags = EDIT_UPDATE | EDIT_DEFER_UPDATES | EDIT_AUTOSUMMARY | ( $minor ? EDIT_MINOR : 0 ) | ( $forceBot ? EDIT_FORCE_BOT : 0 ); $good = $this->doEdit( $text, $summary, $flags ); if ( $good ) { - $dbw =& wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER ); if ($watchthis) { if (!$this->mTitle->userIsWatching()) { $dbw->begin(); @@ -1212,7 +1227,7 @@ class Article { /** * Article::doEdit() * - * Change an existing article or create a new article. Updates RC and all necessary caches, + * Change an existing article or create a new article. Updates RC and all necessary caches, * optionally via the deferred update array. * * $wgUser must be set before calling this function. @@ -1232,9 +1247,11 @@ class Article { * Mark the edit a "bot" edit regardless of user rights * EDIT_DEFER_UPDATES * Defer some of the updates until the end of index.php - * - * If neither EDIT_NEW nor EDIT_UPDATE is specified, the status of the article will be detected. - * If EDIT_UPDATE is specified and the article doesn't exist, the function will return false. If + * EDIT_AUTOSUMMARY + * Fill in blank summaries with generated text where possible + * + * If neither EDIT_NEW nor EDIT_UPDATE is specified, the status of the article will be detected. + * If EDIT_UPDATE is specified and the article doesn't exist, the function will return false. If * EDIT_NEW is specified and the article does exist, a duplicate key error will cause an exception * to be thrown from the Database. These two conditions are also possible with auto-detection due * to MediaWiki's performance-optimised locking strategy. @@ -1258,7 +1275,7 @@ class Article { if( !wfRunHooks( 'ArticleSave', array( &$this, &$wgUser, &$text, &$summary, $flags & EDIT_MINOR, - null, null, &$flags ) ) ) + null, null, &$flags ) ) ) { wfDebug( __METHOD__ . ": ArticleSave hook aborted save!\n" ); wfProfileOut( __METHOD__ ); @@ -1269,19 +1286,19 @@ class Article { $isminor = ( $flags & EDIT_MINOR ) && $wgUser->isAllowed('minoredit'); $bot = $wgUser->isAllowed( 'bot' ) || ( $flags & EDIT_FORCE_BOT ); - # If no edit comment was given when creating a new page, and what's being - # created is a redirect, be smart and fill in a neat auto-comment - if( $summary == '' ) { - $rt = Title::newFromRedirect( $text ); - if( is_object( $rt ) ) - $summary = wfMsgForContent( 'autoredircomment', $rt->getPrefixedText() ); - } + $oldtext = $this->getContent(); + $oldsize = strlen( $oldtext ); + + # Provide autosummaries if one is not provided. + if ($flags & EDIT_AUTOSUMMARY && $summary == '') + $summary = $this->getAutosummary( $oldtext, $text, $flags ); $text = $this->preSaveTransform( $text ); + $newsize = strlen( $text ); - $dbw =& wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER ); $now = wfTimestampNow(); - + if ( $flags & EDIT_UPDATE ) { # Update article, but only if changed. @@ -1290,9 +1307,6 @@ class Article { $userAbort = ignore_user_abort( true ); } - $oldtext = $this->getContent(); - $oldsize = strlen( $oldtext ); - $newsize = strlen( $text ); $lastRevision = 0; $revisionId = 0; @@ -1310,7 +1324,7 @@ class Article { wfProfileOut( __METHOD__ ); return false; } - + $revision = new Revision( array( 'page' => $this->getId(), 'comment' => $summary, @@ -1334,12 +1348,14 @@ class Article { $rcid = RecentChange::notifyEdit( $now, $this->mTitle, $isminor, $wgUser, $summary, $lastRevision, $this->getTimestamp(), $bot, '', $oldsize, $newsize, $revisionId ); - - # Mark as patrolled if the user can do so and has it set in their options - if( $wgUser->isAllowed( 'patrol' ) && $wgUser->getOption( 'autopatrol' ) ) { + + # Mark as patrolled if the user can do so + if( $GLOBALS['wgUseRCPatrol'] && $wgUser->isAllowed( 'autopatrol' ) ) { RecentChange::markPatrolled( $rcid ); + PatrolLog::record( $rcid, true ); } } + $wgUser->incEditCount(); $dbw->commit(); } } else { @@ -1355,19 +1371,19 @@ class Article { } if ( $good ) { - # Invalidate cache of this article and all pages using this article + # Invalidate cache of this article and all pages using this article # as a template. Partly deferred. Article::onArticleEdit( $this->mTitle ); - + # Update links tables, site stats, etc. $changed = ( strcmp( $oldtext, $text ) != 0 ); $this->editUpdates( $text, $summary, $isminor, $now, $revisionId, $changed ); } } else { # Create new article - + # Set statistics members - # We work out if it's countable after PST to avoid counter drift + # We work out if it's countable after PST to avoid counter drift # when articles are created with {{subst:}} $this->mGoodAdjustment = (int)$this->isCountable( $text ); $this->mTotalAdjustment = 1; @@ -1395,11 +1411,13 @@ class Article { if( !( $flags & EDIT_SUPPRESS_RC ) ) { $rcid = RecentChange::notifyNew( $now, $this->mTitle, $isminor, $wgUser, $summary, $bot, '', strlen( $text ), $revisionId ); - # Mark as patrolled if the user can and has the option set - if( $wgUser->isAllowed( 'patrol' ) && $wgUser->getOption( 'autopatrol' ) ) { + # Mark as patrolled if the user can + if( $GLOBALS['wgUseRCPatrol'] && $wgUser->isAllowed( 'autopatrol' ) ) { RecentChange::markPatrolled( $rcid ); + PatrolLog::record( $rcid, true ); } } + $wgUser->incEditCount(); $dbw->commit(); # Update links, etc. @@ -1421,7 +1439,7 @@ class Article { array( &$this, &$wgUser, $text, $summary, $flags & EDIT_MINOR, null, null, &$flags ) ); - + wfProfileOut( __METHOD__ ); return $good; } @@ -1449,40 +1467,66 @@ class Article { } $wgOut->redirect( $this->mTitle->getFullURL( $query ) . $sectionAnchor ); } - + /** * Mark this particular edit as patrolled */ function markpatrolled() { global $wgOut, $wgRequest, $wgUseRCPatrol, $wgUser; - $wgOut->setRobotpolicy( 'noindex,nofollow' ); + $wgOut->setRobotPolicy( 'noindex,nofollow' ); # Check RC patrol config. option if( !$wgUseRCPatrol ) { $wgOut->errorPage( 'rcpatroldisabled', 'rcpatroldisabledtext' ); return; } - + # Check permissions if( !$wgUser->isAllowed( 'patrol' ) ) { $wgOut->permissionRequired( 'patrol' ); return; } - + + # If we haven't been given an rc_id value, we can't do anything $rcid = $wgRequest->getVal( 'rcid' ); - if ( !is_null ( $rcid ) ) { - if( wfRunHooks( 'MarkPatrolled', array( &$rcid, &$wgUser, false ) ) ) { - RecentChange::markPatrolled( $rcid ); - wfRunHooks( 'MarkPatrolledComplete', array( &$rcid, &$wgUser, false ) ); - $wgOut->setPagetitle( wfMsg( 'markedaspatrolled' ) ); - $wgOut->addWikiText( wfMsg( 'markedaspatrolledtext' ) ); - } - $rcTitle = SpecialPage::getTitleFor( 'Recentchanges' ); - $wgOut->returnToMain( false, $rcTitle->getPrefixedText() ); + if( !$rcid ) { + $wgOut->errorPage( 'markedaspatrollederror', 'markedaspatrollederrortext' ); + return; } - else { - $wgOut->showErrorPage( 'markedaspatrollederror', 'markedaspatrollederrortext' ); + + # Handle the 'MarkPatrolled' hook + if( !wfRunHooks( 'MarkPatrolled', array( $rcid, &$wgUser, false ) ) ) { + return; + } + + $return = SpecialPage::getTitleFor( 'Recentchanges' ); + # If it's left up to us, check that the user is allowed to patrol this edit + # If the user has the "autopatrol" right, then we'll assume there are no + # other conditions stopping them doing so + if( !$wgUser->isAllowed( 'autopatrol' ) ) { + $rc = RecentChange::newFromId( $rcid ); + # Graceful error handling, as we've done before here... + # (If the recent change doesn't exist, then it doesn't matter whether + # the user is allowed to patrol it or not; nothing is going to happen + if( is_object( $rc ) && $wgUser->getName() == $rc->getAttribute( 'rc_user_text' ) ) { + # The user made this edit, and can't patrol it + # Tell them so, and then back off + $wgOut->setPageTitle( wfMsg( 'markedaspatrollederror' ) ); + $wgOut->addWikiText( wfMsgNoTrans( 'markedaspatrollederror-noautopatrol' ) ); + $wgOut->returnToMain( false, $return ); + return; + } } + + # Mark the edit as patrolled + RecentChange::markPatrolled( $rcid ); + PatrolLog::record( $rcid ); + wfRunHooks( 'MarkPatrolledComplete', array( &$rcid, &$wgUser, false ) ); + + # Inform the user + $wgOut->setPageTitle( wfMsg( 'markedaspatrolled' ) ); + $wgOut->addWikiText( wfMsgNoTrans( 'markedaspatrolledtext' ) ); + $wgOut->returnToMain( false, $return ); } /** @@ -1501,7 +1545,7 @@ class Article { $wgOut->readOnlyPage(); return; } - + if( $this->doWatch() ) { $wgOut->setPagetitle( wfMsg( 'addedwatch' ) ); $wgOut->setRobotpolicy( 'noindex,nofollow' ); @@ -1513,7 +1557,7 @@ class Article { $wgOut->returnToMain( true, $this->mTitle->getPrefixedText() ); } - + /** * Add this page to $wgUser's watchlist * @return bool true on successful watch operation @@ -1523,13 +1567,13 @@ class Article { if( $wgUser->isAnon() ) { return false; } - + if (wfRunHooks('WatchArticle', array(&$wgUser, &$this))) { $wgUser->addWatch( $this->mTitle ); return wfRunHooks('WatchArticleComplete', array(&$wgUser, &$this)); } - + return false; } @@ -1548,7 +1592,7 @@ class Article { $wgOut->readOnlyPage(); return; } - + if( $this->doUnwatch() ) { $wgOut->setPagetitle( wfMsg( 'removedwatch' ) ); $wgOut->setRobotpolicy( 'noindex,nofollow' ); @@ -1560,7 +1604,7 @@ class Article { $wgOut->returnToMain( true, $this->mTitle->getPrefixedText() ); } - + /** * Stop watching a page * @return bool true on successful unwatch @@ -1576,7 +1620,7 @@ class Article { return wfRunHooks('UnwatchArticleComplete', array(&$wgUser, &$this)); } - + return false; } @@ -1585,7 +1629,7 @@ class Article { */ function protect() { $form = new ProtectionForm( $this ); - $form->show(); + $form->execute(); } /** @@ -1602,14 +1646,21 @@ class Article { * @param string $reason * @return bool true on success */ - function updateRestrictions( $limit = array(), $reason = '' ) { + function updateRestrictions( $limit = array(), $reason = '', $cascade = 0, $expiry = null ) { global $wgUser, $wgRestrictionTypes, $wgContLang; - + $id = $this->mTitle->getArticleID(); if( !$wgUser->isAllowed( 'protect' ) || wfReadOnly() || $id == 0 ) { return false; } + if (!$cascade) { + $cascade = false; + } + + // Take this opportunity to purge out expired restrictions + Title::purgeExpiredRestrictions(); + # FIXME: Same limitations as described in ProtectionForm.php (line 37); # we expect a single selection, but the schema allows otherwise. $current = array(); @@ -1618,48 +1669,82 @@ class Article { $current = Article::flattenRestrictions( $current ); $updated = Article::flattenRestrictions( $limit ); - + $changed = ( $current != $updated ); + $changed = $changed || ($this->mTitle->areRestrictionsCascading() != $cascade); + $changed = $changed || ($this->mTitle->mRestrictionsExpiry != $expiry); $protect = ( $updated != '' ); - + # If nothing's changed, do nothing if( $changed ) { if( wfRunHooks( 'ArticleProtect', array( &$this, &$wgUser, $limit, $reason ) ) ) { - $dbw =& wfGetDB( DB_MASTER ); - + $dbw = wfGetDB( DB_MASTER ); + + $encodedExpiry = Block::encodeExpiry($expiry, $dbw ); + + $expiry_description = ''; + + if ( $encodedExpiry != 'infinity' ) { + $expiry_description = ' (' . wfMsgForContent( 'protect-expiring', $wgContLang->timeanddate( $expiry ) ).')'; + } + # Prepare a null revision to be added to the history $comment = $wgContLang->ucfirst( wfMsgForContent( $protect ? 'protectedarticle' : 'unprotectedarticle', $this->mTitle->getPrefixedText() ) ); + if( $reason ) $comment .= ": $reason"; if( $protect ) $comment .= " [$updated]"; + if ( $expiry_description && $protect ) + $comment .= "$expiry_description"; + $nullRevision = Revision::newNullRevision( $dbw, $id, $comment, true ); $nullRevId = $nullRevision->insertOn( $dbw ); - + + # Update restrictions table + foreach( $limit as $action => $restrictions ) { + if ($restrictions != '' ) { + $dbw->replace( 'page_restrictions', array(array('pr_page', 'pr_type')), + array( 'pr_page' => $id, 'pr_type' => $action + , 'pr_level' => $restrictions, 'pr_cascade' => $cascade ? 1 : 0 + , 'pr_expiry' => $encodedExpiry ), __METHOD__ ); + } else { + $dbw->delete( 'page_restrictions', array( 'pr_page' => $id, + 'pr_type' => $action ), __METHOD__ ); + } + } + # Update page record $dbw->update( 'page', array( /* SET */ 'page_touched' => $dbw->timestamp(), - 'page_restrictions' => $updated, + 'page_restrictions' => '', 'page_latest' => $nullRevId ), array( /* WHERE */ 'page_id' => $id ), 'Article::protect' ); wfRunHooks( 'ArticleProtectComplete', array( &$this, &$wgUser, $limit, $reason ) ); - + # Update the protection log $log = new LogPage( 'protect' ); + + $cascade_description = ''; + + if ($cascade) { + $cascade_description = ' ['.wfMsg('protect-summary-cascade').']'; + } + if( $protect ) { - $log->addEntry( 'protect', $this->mTitle, trim( $reason . " [$updated]" ) ); + $log->addEntry( 'protect', $this->mTitle, trim( $reason . " [$updated]$cascade_description$expiry_description" ) ); } else { $log->addEntry( 'unprotect', $this->mTitle, $reason ); } - + } # End hook } # End "changed" check - + return true; } @@ -1712,9 +1797,9 @@ class Article { } $wgOut->setPagetitle( wfMsg( 'confirmdelete' ) ); - + # Better double-check that it hasn't been deleted yet! - $dbw =& wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER ); $conds = $this->mTitle->pageCond(); $latest = $dbw->selectField( 'page', 'page_latest', $conds, __METHOD__ ); if ( $latest === false ) { @@ -1724,6 +1809,11 @@ class Article { if( $confirm ) { $this->doDelete( $reason ); + if( $wgRequest->getCheck( 'wpWatch' ) ) { + $this->doWatch(); + } elseif( $this->mTitle->userIsWatching() ) { + $this->doUnwatch(); + } return; } @@ -1731,7 +1821,7 @@ class Article { # and insert a warning if it does $maxRevisions = 20; $authors = $this->getLastNAuthors( $maxRevisions, $latest ); - + if( count( $authors ) > 1 && !$confirm ) { $skin=$wgUser->getSkin(); $wgOut->addHTML( '' . wfMsg( 'historywarning' ) . ' ' . $skin->historyLink() . '' ); @@ -1811,7 +1901,7 @@ class Article { // First try the slave // If that doesn't have the latest revision, try the master $continue = 2; - $db =& wfGetDB( DB_SLAVE ); + $db = wfGetDB( DB_SLAVE ); do { $res = $db->select( array( 'page', 'revision' ), array( 'rev_id', 'rev_user_text' ), @@ -1830,7 +1920,7 @@ class Article { } $row = $db->fetchObject( $res ); if ( $continue == 2 && $revLatest && $row->rev_id != $revLatest ) { - $db =& wfGetDB( DB_MASTER ); + $db = wfGetDB( DB_MASTER ); $continue--; } else { $continue = 0; @@ -1844,7 +1934,7 @@ class Article { wfProfileOut( __METHOD__ ); return $authors; } - + /** * Output deletion confirmation dialog */ @@ -1863,6 +1953,7 @@ class Article { $confirm = htmlspecialchars( wfMsg( 'deletepage' ) ); $delcom = htmlspecialchars( wfMsg( 'deletecomment' ) ); $token = htmlspecialchars( $wgUser->editToken() ); + $watch = Xml::checkLabel( wfMsg( 'watchthis' ), 'wpWatch', 'wpWatch', $wgUser->getBoolOption( 'watchdeletion' ) || $this->mTitle->userIsWatching(), array( 'tabindex' => '2' ) ); $wgOut->addHTML( "
@@ -1872,13 +1963,17 @@ class Article { - + + +   + $watch +   - + @@ -1886,6 +1981,23 @@ class Article {
\n" ); $wgOut->returnToMain( false ); + + $this->showLogExtract( $wgOut ); + } + + + /** + * Fetch deletion log + */ + function showLogExtract( &$out ) { + # Show relevant lines from the deletion log: + $out->addHTML( "

" . htmlspecialchars( LogPage::logName( 'delete' ) ) . "

\n" ); + $logViewer = new LogViewer( + new LogReader( + new FauxRequest( + array( 'page' => $this->mTitle->getPrefixedText(), + 'type' => 'delete' ) ) ) ); + $logViewer->showList( $out ); } @@ -1922,11 +2034,11 @@ class Article { */ function doDeleteArticle( $reason ) { global $wgUseSquid, $wgDeferredUpdateList; - global $wgPostCommitUpdateList, $wgUseTrackbacks; + global $wgUseTrackbacks; wfDebug( __METHOD__."\n" ); - $dbw =& wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER ); $ns = $this->mTitle->getNamespace(); $t = $this->mTitle->getDBkey(); $id = $this->mTitle->getArticleID(); @@ -1959,12 +2071,18 @@ class Article { 'ar_minor_edit' => 'rev_minor_edit', 'ar_rev_id' => 'rev_id', 'ar_text_id' => 'rev_text_id', + 'ar_text' => '\'\'', // Be explicit to appease + 'ar_flags' => '\'\'', // MySQL's "strict mode"... + 'ar_len' => 'rev_len' ), array( 'page_id' => $id, 'page_id = rev_page' ), __METHOD__ ); + # Delete restrictions for it + $dbw->delete( 'page_restrictions', array ( 'pr_page' => $id ), __METHOD__ ); + # Now that it's safely backed up, delete it $dbw->delete( 'page', array( 'page_id' => $id ), __METHOD__); @@ -2033,14 +2151,12 @@ class Article { $wgOut->addWikiText( wfMsg( 'sessionfailure' ) ); return; } - $dbw =& wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER ); # Enhanced rollback, marks edits rc_bot=1 $bot = $wgRequest->getBool( 'bot' ); # Replace all this user's current edits with the next one down - $tt = $this->mTitle->getDBKey(); - $n = $this->mTitle->getNamespace(); # Get the last editor $current = Revision::newFromTitle( $this->mTitle ); @@ -2060,7 +2176,7 @@ class Article { if( $current->getComment() != '') { $wgOut->addHTML( wfMsg( 'editcomment', - htmlspecialchars( $current->getComment() ) ) ); + $wgUser->getSkin()->formatComment( $current->getComment() ) ) ); } return; } @@ -2146,7 +2262,7 @@ class Article { * Do standard deferred updates after page edit. * Update links tables, site stats, search index and message cache. * Every 1000th edit, prune the recent changes table. - * + * * @private * @param $text New text of the article * @param $summary Edit summary @@ -2179,7 +2295,7 @@ class Article { # Periodically flush old entries from the recentchanges table. global $wgRCMaxAge; - $dbw =& wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER ); $cutoff = $dbw->timestamp( time() - $wgRCMaxAge ); $recentchanges = $dbw->tableName( 'recentchanges' ); $sql = "DELETE FROM $recentchanges WHERE rc_timestamp < '{$cutoff}'"; @@ -2226,13 +2342,13 @@ class Article { wfProfileOut( __METHOD__ ); } - + /** * Perform article updates on a special page creation. * * @param Revision $rev * - * @fixme This is a shitty interface function. Kill it and replace the + * @todo This is a shitty interface function. Kill it and replace the * other shitty functions like editUpdates and such so it's not needed * anymore. */ @@ -2253,37 +2369,42 @@ class Article { * @param string $oldid Revision ID of this article revision */ function setOldSubtitle( $oldid=0 ) { - global $wgLang, $wgOut; + global $wgLang, $wgOut, $wgUser; if ( !wfRunHooks( 'DisplayOldSubtitle', array(&$this, &$oldid) ) ) { - return; - } + return; + } $revision = Revision::newFromId( $oldid ); $current = ( $oldid == $this->mLatest ); $td = $wgLang->timeanddate( $this->mTimestamp, true ); + $sk = $wgUser->getSkin(); $lnk = $current ? wfMsg( 'currentrevisionlink' ) - : $lnk = Linker::makeKnownLinkObj( $this->mTitle, wfMsg( 'currentrevisionlink' ) ); + : $lnk = $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'currentrevisionlink' ) ); + $curdiff = $current + ? wfMsg( 'diff' ) + : $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'diff' ), 'diff=cur&oldid='.$oldid ); $prev = $this->mTitle->getPreviousRevisionID( $oldid ) ; $prevlink = $prev - ? Linker::makeKnownLinkObj( $this->mTitle, wfMsg( 'previousrevision' ), 'direction=prev&oldid='.$oldid ) + ? $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'previousrevision' ), 'direction=prev&oldid='.$oldid ) : wfMsg( 'previousrevision' ); $prevdiff = $prev - ? Linker::makeKnownLinkObj( $this->mTitle, wfMsg( 'diff' ), 'diff=prev&oldid='.$oldid ) + ? $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'diff' ), 'diff=prev&oldid='.$oldid ) : wfMsg( 'diff' ); $nextlink = $current ? wfMsg( 'nextrevision' ) - : Linker::makeKnownLinkObj( $this->mTitle, wfMsg( 'nextrevision' ), 'direction=next&oldid='.$oldid ); + : $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'nextrevision' ), 'direction=next&oldid='.$oldid ); $nextdiff = $current ? wfMsg( 'diff' ) - : Linker::makeKnownLinkObj( $this->mTitle, wfMsg( 'diff' ), 'diff=next&oldid='.$oldid ); - - $userlinks = Linker::userLink( $revision->getUser(), $revision->getUserText() ) - . Linker::userToolLinks( $revision->getUser(), $revision->getUserText() ); - - $r = wfMsg( 'old-revision-navigation', $td, $lnk, $prevlink, $nextlink, $userlinks, $prevdiff, $nextdiff ); + : $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'diff' ), 'diff=next&oldid='.$oldid ); + + $userlinks = $sk->userLink( $revision->getUser(), $revision->getUserText() ) + . $sk->userToolLinks( $revision->getUser(), $revision->getUserText() ); + + $r = "\n\t\t\t\t
" . wfMsg( 'revision-info', $td, $userlinks ) . "
\n" . + "\n\t\t\t\t
" . wfMsg( 'revision-nav', $prevdiff, $prevlink, $lnk, $curdiff, $nextlink, $nextdiff ) . "
\n\t\t\t"; $wgOut->setSubtitle( $r ); } @@ -2334,7 +2455,11 @@ class Article { */ function isFileCacheable() { global $wgUser, $wgUseFileCache, $wgShowIPinHeader, $wgRequest; - extract( $wgRequest->getValues( 'action', 'oldid', 'diff', 'redirect', 'printable' ) ); + $action = $wgRequest->getVal( 'action' ); + $oldid = $wgRequest->getVal( 'oldid' ); + $diff = $wgRequest->getVal( 'diff' ); + $redirect = $wgRequest->getVal( 'redirect' ); + $printable = $wgRequest->getVal( 'printable' ); return $wgUseFileCache and (!$wgShowIPinHeader) @@ -2394,7 +2519,7 @@ class Article { function quickEdit( $text, $comment = '', $minor = 0 ) { wfProfileIn( __METHOD__ ); - $dbw =& wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER ); $dbw->begin(); $revision = new Revision( array( 'page' => $this->getId(), @@ -2402,8 +2527,7 @@ class Article { 'comment' => $comment, 'minor_edit' => $minor ? 1 : 0, ) ); - # fixme : $revisionId never used - $revisionId = $revision->insertOn( $dbw ); + $revision->insertOn( $dbw ); $this->updateRevisionOn( $dbw, $revision ); $dbw->commit(); @@ -2420,12 +2544,12 @@ class Article { $id = intval( $id ); global $wgHitcounterUpdateFreq, $wgDBtype; - $dbw =& wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER ); $pageTable = $dbw->tableName( 'page' ); $hitcounterTable = $dbw->tableName( 'hitcounter' ); $acchitsTable = $dbw->tableName( 'acchits' ); - if( $wgHitcounterUpdateFreq <= 1 ){ // + if( $wgHitcounterUpdateFreq <= 1 ) { $dbw->query( "UPDATE $pageTable SET page_counter = page_counter + 1 WHERE page_id = $id" ); return; } @@ -2452,14 +2576,19 @@ class Article { if ($wgDBtype == 'mysql') $dbw->query("LOCK TABLES $hitcounterTable WRITE"); $tabletype = $wgDBtype == 'mysql' ? "ENGINE=HEAP " : ''; - $dbw->query("CREATE TEMPORARY TABLE $acchitsTable $tabletype". + $dbw->query("CREATE TEMPORARY TABLE $acchitsTable $tabletype AS ". "SELECT hc_id,COUNT(*) AS hc_n FROM $hitcounterTable ". 'GROUP BY hc_id'); $dbw->query("DELETE FROM $hitcounterTable"); - if ($wgDBtype == 'mysql') + if ($wgDBtype == 'mysql') { $dbw->query('UNLOCK TABLES'); - $dbw->query("UPDATE $pageTable,$acchitsTable SET page_counter=page_counter + hc_n ". - 'WHERE page_id = hc_id'); + $dbw->query("UPDATE $pageTable,$acchitsTable SET page_counter=page_counter + hc_n ". + 'WHERE page_id = hc_id'); + } + else { + $dbw->query("UPDATE $pageTable SET page_counter=page_counter + hc_n ". + "FROM $acchitsTable WHERE page_id = hc_id"); + } $dbw->query("DROP TABLE $acchitsTable"); ignore_user_abort( $old_user_abort ); @@ -2499,7 +2628,7 @@ class Article { $title->touchLinks(); $title->purgeSquid(); - + # File cache if ( $wgUseFileCache ) { $cm = new HTMLFileCache( $title ); @@ -2517,8 +2646,6 @@ class Article { static function onArticleEdit( $title ) { global $wgDeferredUpdateList, $wgUseFileCache; - $urls = array(); - // Invalidate caches of articles which include this page $update = new HTMLCacheUpdate( $title, 'templatelinks' ); $wgDeferredUpdateList[] = $update; @@ -2563,7 +2690,7 @@ class Article { $wgOut->addHTML(wfMsg( $wgUser->isLoggedIn() ? 'noarticletext' : 'noarticletextanon' ) ); } } else { - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $wl_clause = array( 'wl_title' => $page->getDBkey(), 'wl_namespace' => $page->getNamespace() ); @@ -2605,7 +2732,7 @@ class Article { return false; } - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $rev_clause = array( 'rev_page' => $id ); @@ -2639,7 +2766,7 @@ class Article { return array(); } - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $res = $dbr->select( array( 'templatelinks' ), array( 'tl_namespace', 'tl_title' ), array( 'tl_from' => $id ), @@ -2654,6 +2781,161 @@ class Article { $dbr->freeResult( $res ); return $result; } + + /** + * Return an auto-generated summary if the text provided is a redirect. + * + * @param string $text The wikitext to check + * @return string '' or an appropriate summary + */ + public static function getRedirectAutosummary( $text ) { + $rt = Title::newFromRedirect( $text ); + if( is_object( $rt ) ) + return wfMsgForContent( 'autoredircomment', $rt->getFullText() ); + else + return ''; + } + + /** + * Return an auto-generated summary if the new text is much shorter than + * the old text. + * + * @param string $oldtext The previous text of the page + * @param string $text The submitted text of the page + * @return string An appropriate autosummary, or an empty string. + */ + public static function getBlankingAutosummary( $oldtext, $text ) { + if ($oldtext!='' && $text=='') { + return wfMsgForContent('autosumm-blank'); + } elseif (strlen($oldtext) > 10 * strlen($text) && strlen($text) < 500) { + #Removing more than 90% of the article + global $wgContLang; + $truncatedtext = $wgContLang->truncate($text, max(0, 200 - strlen(wfMsgForContent('autosumm-replace'))), '...'); + return wfMsgForContent('autosumm-replace', $truncatedtext); + } else { + return ''; + } + } + + /** + * Return an applicable autosummary if one exists for the given edit. + * @param string $oldtext The previous text of the page. + * @param string $newtext The submitted text of the page. + * @param bitmask $flags A bitmask of flags submitted for the edit. + * @return string An appropriate autosummary, or an empty string. + */ + public static function getAutosummary( $oldtext, $newtext, $flags ) { + + # This code is UGLY UGLY UGLY. + # Somebody PLEASE come up with a more elegant way to do it. + + #Redirect autosummaries + $summary = self::getRedirectAutosummary( $newtext ); + + if ($summary) + return $summary; + + #Blanking autosummaries + if (!($flags & EDIT_NEW)) + $summary = self::getBlankingAutosummary( $oldtext, $newtext ); + + if ($summary) + return $summary; + + #New page autosummaries + if ($flags & EDIT_NEW && strlen($newtext)) { + #If they're making a new article, give its text, truncated, in the summary. + global $wgContLang; + $truncatedtext = $wgContLang->truncate( + str_replace("\n", ' ', $newtext), + max( 0, 200 - strlen( wfMsgForContent( 'autosumm-new') ) ), + '...' ); + $summary = wfMsgForContent( 'autosumm-new', $truncatedtext ); + } + + if ($summary) + return $summary; + + return $summary; + } + + /** + * Add the primary page-view wikitext to the output buffer + * Saves the text into the parser cache if possible. + * Updates templatelinks if it is out of date. + * + * @param string $text + * @param bool $cache + */ + public function outputWikiText( $text, $cache = true ) { + global $wgParser, $wgUser, $wgOut; + + $popts = $wgOut->parserOptions(); + $popts->setTidy(true); + $parserOutput = $wgParser->parse( $text, $this->mTitle, + $popts, true, true, $this->getRevIdFetched() ); + $popts->setTidy(false); + if ( $cache && $this && $parserOutput->getCacheTime() != -1 ) { + $parserCache =& ParserCache::singleton(); + $parserCache->save( $parserOutput, $this, $wgUser ); + } + + if ( !wfReadOnly() && $this->mTitle->areRestrictionsCascading() ) { + // templatelinks table may have become out of sync, + // especially if using variable-based transclusions. + // For paranoia, check if things have changed and if + // so apply updates to the database. This will ensure + // that cascaded protections apply as soon as the changes + // are visible. + + # Get templates from templatelinks + $id = $this->mTitle->getArticleID(); + + $tlTemplates = array(); + + $dbr = wfGetDB( DB_SLAVE ); + $res = $dbr->select( array( 'templatelinks' ), + array( 'tl_namespace', 'tl_title' ), + array( 'tl_from' => $id ), + 'Article:getUsedTemplates' ); + + global $wgContLang; + + if ( false !== $res ) { + if ( $dbr->numRows( $res ) ) { + while ( $row = $dbr->fetchObject( $res ) ) { + $tlTemplates[] = $wgContLang->getNsText( $row->tl_namespace ) . ':' . $row->tl_title ; + } + } + } + + # Get templates from parser output. + $poTemplates_allns = $parserOutput->getTemplates(); + + $poTemplates = array (); + foreach ( $poTemplates_allns as $ns_templates ) { + $poTemplates = array_merge( $poTemplates, $ns_templates ); + } + + # Get the diff + $templates_diff = array_diff( $poTemplates, $tlTemplates ); + + if ( count( $templates_diff ) > 0 ) { + # Whee, link updates time. + $u = new LinksUpdate( $this->mTitle, $parserOutput ); + + $dbw = wfGetDb( DB_MASTER ); + $dbw->begin(); + + $u->doUpdate(); + + $dbw->commit(); + } + } + + $wgOut->addParserOutput( $parserOutput ); + } + } ?>