X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FArticle.php;h=1e7f44316ed8458f9e127b44016d99b4c2b70507;hb=f001c1cdad1619ee8f33b8e8d65965d6dae54943;hp=b3619760086a8192f71963f10b0b4d366a0b6dbe;hpb=0b7ae97a8a85b49cbe7aed2cb5476432688a572c;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Article.php b/includes/Article.php index b361976008..1e7f44316e 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -1,14 +1,14 @@ clear(); } + /** + * get the title object of the article + * @public + */ + function getTitle() { + return $this->mTitle; + } + /** * Clear the object * @private @@ -59,91 +67,6 @@ class Article { $this->mForUpdate = false; } - /** - * Get revision text associated with an old or archive row - * $row is usually an object from wfFetchRow(), both the flags and the text - * field must be included - * @static - * @param integer $row Id of a row - * @param string $prefix table prefix (default 'old_') - * @return string $text|false the text requested - */ - function getRevisionText( $row, $prefix = 'old_' ) { - # Get data - $textField = $prefix . 'text'; - $flagsField = $prefix . 'flags'; - - if( isset( $row->$flagsField ) ) { - $flags = explode( ',', $row->$flagsField ); - } else { - $flags = array(); - } - - if( isset( $row->$textField ) ) { - $text = $row->$textField; - } else { - return false; - } - - if( in_array( 'gzip', $flags ) ) { - # Deal with optional compression of archived pages. - # This can be done periodically via maintenance/compressOld.php, and - # as pages are saved if $wgCompressRevisions is set. - $text = gzinflate( $text ); - } - - if( in_array( 'object', $flags ) ) { - # Generic compressed storage - $obj = unserialize( $text ); - - # Bugger, corrupted my test database by double-serializing - if ( !is_object( $obj ) ) { - $obj = unserialize( $obj ); - } - - $text = $obj->getText(); - } - - global $wgLegacyEncoding; - if( $wgLegacyEncoding && !in_array( 'utf-8', $flags ) ) { - # Old revisions kept around in a legacy encoding? - # Upconvert on demand. - global $wgInputEncoding, $wgContLang; - $text = $wgContLang->iconv( $wgLegacyEncoding, $wgInputEncoding, $text ); - } - return $text; - } - - /** - * If $wgCompressRevisions is enabled, we will compress data. - * The input string is modified in place. - * Return value is the flags field: contains 'gzip' if the - * data is compressed, and 'utf-8' if we're saving in UTF-8 - * mode. - * - * @static - * @param mixed $text reference to a text - * @return string - */ - function compressRevisionText( &$text ) { - global $wgCompressRevisions, $wgUseLatin1; - $flags = array(); - if( !$wgUseLatin1 ) { - # Revisions not marked this way will be converted - # on load if $wgLegacyCharset is set in the future. - $flags[] = 'utf-8'; - } - if( $wgCompressRevisions ) { - if( function_exists( 'gzdeflate' ) ) { - $text = gzdeflate( $text ); - $flags[] = 'gzip'; - } else { - wfDebug( "Article::compressRevisionText() -- no zlib support, not compressing\n" ); - } - } - return implode( ',', $flags ); - } - /** * Note that getContent/loadContent may follow redirects if * not told otherwise, and so may cause a change to mTitle. @@ -270,25 +193,11 @@ class Article { /** * Return an array of the columns of the "cur"-table */ - function &getCurContentFields() { - global $wgArticleCurContentFields; - if ( !$wgArticleCurContentFields ) { - $wgArticleCurContentFields = array( 'cur_text','cur_timestamp','cur_user', 'cur_user_text', - 'cur_comment','cur_counter','cur_restrictions','cur_touched' ); - } - return $wgArticleCurContentFields; - } - - /** - * Return an array of the columns of the "old"-table - */ - function &getOldContentFields() { - global $wgArticleOldContentFields; - if ( !$wgArticleOldContentFields ) { - $wgArticleOldContentFields = array( 'old_namespace','old_title','old_text','old_timestamp', - 'old_user','old_user_text','old_comment','old_flags' ); - } - return $wgArticleOldContentFields; + function getContentFields() { + return $wgArticleContentFields = array( + 'old_text','old_flags', + 'rev_timestamp','rev_user', 'rev_user_text', 'rev_comment','page_counter', + 'page_namespace', 'page_title', 'page_restrictions','page_touched','page_is_redirect' ); } /** @@ -299,18 +208,17 @@ class Article { function getOldID() { global $wgRequest, $wgOut; static $lastid; - + if ( isset( $lastid ) ) { return $lastid; } - + # Query variables :P $oldid = $wgRequest->getVal( 'oldid' ); if ( isset( $oldid ) ) { - $dbr =& $this->getDB(); $oldid = IntVal( $oldid ); if ( $wgRequest->getVal( 'direction' ) == 'next' ) { $nextid = $this->mTitle->getNextRevisionID( $oldid ); - if ( $nextid ) { + if ( $nextid ) { $oldid = $nextid; } else { $wgOut->redirect( $this->mTitle->getFullURL( 'redirect=no' ) ); @@ -331,13 +239,12 @@ class Article { /** * Load the revision (including cur_text) into this object - */ + */ function loadContent( $noredir = false ) { global $wgOut, $wgRequest; if ( $this->mContentLoaded ) return; - $dbr =& $this->getDB(); # Query variables :P $oldid = $this->getOldID(); $redirect = $wgRequest->getVal( 'redirect' ); @@ -349,86 +256,118 @@ class Article { $t = $this->mTitle->getPrefixedText(); - if ( isset( $oldid ) ) { + $noredir = $noredir || ($wgRequest->getVal( 'redirect' ) == 'no'); + $this->mOldId = $oldid; + $this->fetchContent( $oldid, $noredir, true ); + } + + /** + * Get text of an article from database + * @param int $oldid 0 for whatever the latest revision is + * @param bool $noredir Set to true to avoid following redirects + * @param bool $globalTitle Set to true to change the global $wgTitle object when following redirects or other unexpected title changes + * @return string + */ + function fetchContent( $oldid = 0, $noredir = false, $globalTitle = false ) { + if ( $this->mContentLoaded ) { + return $this->mContent; + } + $dbr =& $this->getDB(); + $fname = 'Article::fetchContent'; + + # 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( $oldid ) { $t .= ',oldid='.$oldid; } - if ( isset( $redirect ) ) { + if( isset( $redirect ) ) { $redirect = ($redirect == 'no') ? 'no' : 'yes'; $t .= ',redirect='.$redirect; } $this->mContent = wfMsg( 'missingarticle', $t ); - if ( ! $oldid ) { # Retrieve current version + if( !$oldid ) { + # Retrieve current version $id = $this->getID(); - if ( 0 == $id ) return; - - $s = $dbr->selectRow( 'cur', $this->getCurContentFields(), array( 'cur_id' => $id ), $fname, - $this->getSelectOptions() ); - if ( $s === false ) { - return; + if ( 0 == $id ) { + return false; } - # If we got a redirect, follow it (unless we've been told - # not to by either the function parameter or the query - if ( ( 'no' != $redirect ) && ( false == $noredir ) ) { - $rt = Title::newFromRedirect( $s->cur_text ); - # process if title object is valid and not special:userlogout - if ( $rt && ! ( $rt->getNamespace() == NS_SPECIAL && $rt->getText() == 'Userlogout' ) ) { - # Gotta hand redirects to special pages differently: - # Fill the HTTP response "Location" header and ignore - # the rest of the page we're on. + $s = $dbr->selectRow( array( 'text', 'revision', 'page' ), + $this->getContentFields(), + "page_id='$id' AND rev_page=page_id AND rev_id=page_latest AND old_id=rev_id", + $fname, $this->getSelectOptions() ); + } else { + # Historical revision + $s = $dbr->selectRow( array( 'text', 'revision', 'page' ), + $this->getContentFields(), + "rev_page=page_id AND rev_id='$oldid' AND old_id=rev_id", + $fname, $this->getSelectOptions() ); + } + if ( $s === false ) { + return false; + } + # If we got a redirect, follow it (unless we've been told + # not to by either the function parameter or the query + if ( !$oldid && !$noredir ) { + $rt = Title::newFromRedirect( Revision::getRevisionText( $s ) ); + # process if title object is valid and not special:userlogout + if ( $rt && ! ( $rt->getNamespace() == NS_SPECIAL && $rt->getText() == 'Userlogout' ) ) { + # Gotta hand redirects to special pages differently: + # Fill the HTTP response "Location" header and ignore + # the rest of the page we're on. + if( $globalTitle ) { + global $wgOut; if ( $rt->getInterwiki() != '' ) { $wgOut->redirect( $rt->getFullURL() ) ; - return; + return false; } if ( $rt->getNamespace() == NS_SPECIAL ) { $wgOut->redirect( $rt->getFullURL() ); - return; + return false; } - $rid = $rt->getArticleID(); - if ( 0 != $rid ) { - $redirRow = $dbr->selectRow( 'cur', $this->getCurContentFields(), - array( 'cur_id' => $rid ), $fname, $this->getSelectOptions() ); - - if ( $redirRow !== false ) { - $this->mRedirectedFrom = $this->mTitle->getPrefixedText(); - $this->mTitle = $rt; - $s = $redirRow; - } + } + $rid = $rt->getArticleID(); + if ( 0 != $rid ) { + $redirRow = $dbr->selectRow( array( 'text', 'revision', 'page' ), + $this->getContentFields(), + "page_id='$rid' AND rev_page=page_id AND rev_id=page_latest AND old_id=rev_id", + $fname, $this->getSelectOptions() ); + + if ( $redirRow !== false ) { + $this->mRedirectedFrom = $this->mTitle->getPrefixedText(); + $this->mTitle = $rt; + $s = $redirRow; } } } + } - $this->mContent = $s->cur_text; - $this->mUser = $s->cur_user; - $this->mUserText = $s->cur_user_text; - $this->mComment = $s->cur_comment; - $this->mCounter = $s->cur_counter; - $this->mTimestamp = wfTimestamp(TS_MW,$s->cur_timestamp); - $this->mTouched = wfTimestamp(TS_MW,$s->cur_touched); - $this->mTitle->mRestrictions = explode( ',', trim( $s->cur_restrictions ) ); - $this->mTitle->mRestrictionsLoaded = true; - } else { # oldid set, retrieve historical version - $s = $dbr->selectRow( 'old', $this->getOldContentFields(), array( 'old_id' => $oldid ), - $fname, $this->getSelectOptions() ); - if ( $s === false ) { - return; - } - - if( $this->mTitle->getNamespace() != $s->old_namespace || - $this->mTitle->getDBkey() != $s->old_title ) { - $oldTitle = Title::makeTitle( $s->old_namesapce, $s->old_title ); - $this->mTitle = $oldTitle; - $wgTitle = $oldTitle; - } - $this->mContent = Article::getRevisionText( $s ); - $this->mUser = $s->old_user; - $this->mUserText = $s->old_user_text; - $this->mComment = $s->old_comment; - $this->mCounter = 0; - $this->mTimestamp = wfTimestamp(TS_MW,$s->old_timestamp); + # if the title's different from expected, update... + if( $globalTitle && + ( $this->mTitle->getNamespace() != $s->page_namespace || + $this->mTitle->getDBkey() != $s->page_title ) ) { + $oldTitle = Title::makeTitle( $s->page_namesapce, $s->page_title ); + $this->mTitle = $oldTitle; + global $wgTitle; + $wgTitle = $oldTitle; } + + # Back to the business at hand... + $this->mCounter = $s->page_counter; + $this->mTitle->mRestrictions = explode( ',', trim( $s->page_restrictions ) ); + $this->mTitle->mRestrictionsLoaded = true; + $this->mTouched = wfTimestamp( TS_MW, $s->page_touched ); + + $this->mContent = Revision::getRevisionText( $s ); + + $this->mUser = $s->rev_user; + $this->mUserText = $s->rev_user_text; + $this->mComment = $s->rev_comment; + $this->mTimestamp = wfTimestamp( TS_MW, $s->rev_timestamp ); + $this->mContentLoaded = true; return $this->mContent; } @@ -440,69 +379,7 @@ class Article { * @param integer $oldid */ function getContentWithoutUsingSoManyDamnGlobals( $oldid = 0, $noredir = false ) { - if ( $this->mContentLoaded ) { - return $this->mContent; - } - $this->mContent = false; - - $fname = 'Article::getContentWithout'; - $dbr =& $this->getDB(); - - if ( ! $oldid ) { # Retrieve current version - $id = $this->getID(); - if ( 0 == $id ) { - return false; - } - - $s = $dbr->selectRow( 'cur', $this->getCurContentFields(), array( 'cur_id' => $id ), - $fname, $this->getSelectOptions() ); - if ( $s === false ) { - return false; - } - - # If we got a redirect, follow it (unless we've been told - # not to by either the function parameter or the query - if ( !$noredir ) { - $rt = Title::newFromRedirect( $s->cur_text ); - if( $rt && $rt->getInterwiki() == '' && $rt->getNamespace() != NS_SPECIAL ) { - $rid = $rt->getArticleID(); - if ( 0 != $rid ) { - $redirRow = $dbr->selectRow( 'cur', $this->getCurContentFields(), - array( 'cur_id' => $rid ), $fname, $this->getSelectOptions() ); - - if ( $redirRow !== false ) { - $this->mRedirectedFrom = $this->mTitle->getPrefixedText(); - $this->mTitle = $rt; - $s = $redirRow; - } - } - } - } - - $this->mContent = $s->cur_text; - $this->mUser = $s->cur_user; - $this->mUserText = $s->cur_user_text; - $this->mComment = $s->cur_comment; - $this->mCounter = $s->cur_counter; - $this->mTimestamp = wfTimestamp(TS_MW,$s->cur_timestamp); - $this->mTouched = wfTimestamp(TS_MW,$s->cur_touched); - $this->mTitle->mRestrictions = explode( ',', trim( $s->cur_restrictions ) ); - $this->mTitle->mRestrictionsLoaded = true; - } else { # oldid set, retrieve historical version - $s = $dbr->selectRow( 'old', $this->getOldContentFields(), array( 'old_id' => $oldid ), - $fname, $this->getSelectOptions() ); - if ( $s === false ) { - return false; - } - $this->mContent = Article::getRevisionText( $s ); - $this->mUser = $s->old_user; - $this->mUserText = $s->old_user_text; - $this->mComment = $s->old_comment; - $this->mCounter = 0; - $this->mTimestamp = wfTimestamp(TS_MW,$s->old_timestamp); - } - $this->mContentLoaded = true; - return $this->mContent; + return $this->fetchContent( $oldid, $noredir, false ); } /** @@ -529,7 +406,7 @@ class Article { */ function getSelectOptions( $options = '' ) { if ( $this->mForUpdate ) { - if ( $options ) { + if ( is_array( $options ) ) { $options[] = 'FOR UPDATE'; } else { $options = 'FOR UPDATE'; @@ -556,7 +433,7 @@ class Article { if ( -1 == $this->mCounter ) { $id = $this->getID(); $dbr =& $this->getDB(); - $this->mCounter = $dbr->selectField( 'cur', 'cur_counter', 'cur_id='.$id, + $this->mCounter = $dbr->selectField( 'page', 'page_counter', array( 'page_id' => $id ), 'Article::getCount', $this->getSelectOptions() ); } return $this->mCounter; @@ -565,11 +442,13 @@ class Article { /** * Would the given text make this article a "good" article (i.e., * suitable for including in the article count)? + * @param string $text Text to analyze + * @return integer 1 if it can be counted else 0 */ function isCountable( $text ) { global $wgUseCommaCount; - if ( 0 != $this->mTitle->getNamespace() ) { return 0; } + if ( NS_MAIN != $this->mTitle->getNamespace() ) { return 0; } if ( $this->isRedirect( $text ) ) { return 0; } $token = ($wgUseCommaCount ? ',' : '[[' ); if ( false === strstr( $text, $token ) ) { return 0; } @@ -590,27 +469,33 @@ class Article { } /** - * Loads everything from cur except cur_text + * Loads everything except the text * This isn't necessary for all uses, so it's only done if needed. * @private */ function loadLastEdit() { global $wgOut; - if ( -1 != $this->mUser ) return; + + if ( -1 != $this->mUser ) + return; + + # New or non-existent articles have no user information + $id = $this->getID(); + if ( 0 == $id ) return; $fname = 'Article::loadLastEdit'; $dbr =& $this->getDB(); - $s = $dbr->selectRow( 'cur', - array( 'cur_user','cur_user_text','cur_timestamp', 'cur_comment','cur_minor_edit' ), - array( 'cur_id' => $this->getID() ), $fname, $this->getSelectOptions() ); + $s = $dbr->selectRow( array( 'revision', 'page') , + array( 'rev_user','rev_user_text','rev_timestamp', 'rev_comment','rev_minor_edit' ), + array( 'page_id' => $id, 'page_latest=rev_id' ), $fname, $this->getSelectOptions() ); if ( $s !== false ) { - $this->mUser = $s->cur_user; - $this->mUserText = $s->cur_user_text; - $this->mTimestamp = wfTimestamp(TS_MW,$s->cur_timestamp); - $this->mComment = $s->cur_comment; - $this->mMinorEdit = $s->cur_minor_edit; + $this->mUser = $s->rev_user; + $this->mUserText = $s->rev_user_text; + $this->mTimestamp = wfTimestamp(TS_MW,$s->rev_timestamp); + $this->mComment = $s->rev_comment; + $this->mMinorEdit = $s->rev_minor_edit; } } @@ -647,18 +532,18 @@ class Article { $title = $this->mTitle; $contribs = array(); $dbr =& $this->getDB(); - $oldTable = $dbr->tableName( 'old' ); + $revTable = $dbr->tableName( 'revision' ); $userTable = $dbr->tableName( 'user' ); $encDBkey = $dbr->addQuotes( $title->getDBkey() ); $ns = $title->getNamespace(); $user = $this->getUser(); + $pageId = $this->getId(); - $sql = "SELECT old_user, old_user_text, user_real_name, MAX(old_timestamp) as timestamp - FROM $oldTable LEFT JOIN $userTable ON old_user = user_id - WHERE old_namespace = $user - AND old_title = $encDBkey - AND old_user != $user - GROUP BY old_user, old_user_text, user_real_name + $sql = "SELECT rev_user, rev_user_text, user_real_name, MAX(rev_timestamp) as timestamp + FROM $revTable LEFT JOIN $userTable ON rev_user = user_id + WHERE rev_page = $pageId + AND rev_user != $user + GROUP BY rev_user, rev_user_text, user_real_name ORDER BY timestamp DESC"; if ($limit > 0) { $sql .= ' LIMIT '.$limit; } @@ -667,7 +552,7 @@ class Article { $res = $dbr->query($sql, $fname); while ( $line = $dbr->fetchObject( $res ) ) { - $contribs[] = array($line->old_user, $line->old_user_text, $line->user_real_name); + $contribs[] = array($line->rev_user, $line->rev_user_text, $line->user_real_name); } $dbr->freeResult($res); @@ -681,6 +566,7 @@ class Article { function view() { global $wgUser, $wgOut, $wgRequest, $wgOnlySysopsCanPatrol, $wgLang; global $wgLinkCache, $IP, $wgEnableParserCache, $wgStylePath, $wgUseRCPatrol; + global $wgEnotif; $sk = $wgUser->getSkin(); $fname = 'Article::view'; @@ -746,7 +632,7 @@ class Article { # We're looking at an old revision if ( !empty( $oldid ) ) { - $this->setOldSubtitle( $oldid ); + $this->setOldSubtitle( isset($this->mOldId) ? $this->mOldId : $oldid ); $wgOut->setRobotpolicy( 'noindex,follow' ); } if ( '' != $this->mRedirectedFrom ) { @@ -806,6 +692,8 @@ class Article { $this->viewUpdates(); wfProfileOut( $fname ); + + $wgUser->clearNotification( $this->mTitle ); } /** @@ -833,32 +721,47 @@ class Article { $won = wfInvertTimestamp( $now ); wfSeedRandom(); $rand = wfRandom(); - $dbw =& wfGetDB( DB_MASTER ); + $isminor = ( $isminor && $wgUser->getID() ) ? 1 : 0; + + $mungedText = $text; + $flags = Revision::compressRevisionText( $mungedText ); - $cur_id = $dbw->nextSequenceValue( 'cur_cur_id_seq' ); + $dbw =& wfGetDB( DB_MASTER ); - $isminor = ( $isminor && $wgUser->getID() ) ? 1 : 0; + $old_id = $dbw->nextSequenceValue( 'text_old_id_seq' ); + $dbw->insert( 'text', array( + 'old_id' => $old_id, + 'old_text' => $mungedText, + 'old_flags' => $flags, + ), $fname ); + $revisionId = $dbw->insertId(); + + $page_id = $dbw->nextSequenceValue( 'page_page_id_seq' ); + $dbw->insert( 'page', array( + 'page_id' => $page_id, + 'page_namespace' => $ns, + 'page_title' => $ttl, + 'page_counter' => 0, + 'page_restrictions' => '', + 'page_is_redirect' => $redir, + 'page_is_new' => 1, + 'page_random' => $rand, + 'page_touched' => $dbw->timestamp($now), + 'page_latest' => $revisionId, + ), $fname ); + $newid = $dbw->insertId(); - $dbw->insert( 'cur', array( - 'cur_id' => $cur_id, - 'cur_namespace' => $ns, - 'cur_title' => $ttl, - 'cur_text' => $text, - 'cur_comment' => $summary, - 'cur_user' => $wgUser->getID(), - 'cur_timestamp' => $dbw->timestamp($now), - 'cur_minor_edit' => $isminor, - 'cur_counter' => 0, - 'cur_restrictions' => '', - 'cur_user_text' => $wgUser->getName(), - 'cur_is_redirect' => $redir, - 'cur_is_new' => 1, - 'cur_random' => $rand, - 'cur_touched' => $dbw->timestamp($now), + $dbw->insert( 'revision', array( + 'rev_page' => $newid, + 'rev_id' => $revisionId, + 'rev_comment' => $summary, + 'rev_user' => $wgUser->getID(), + 'rev_timestamp' => $dbw->timestamp($now), + 'rev_minor_edit' => $isminor, + 'rev_user_text' => $wgUser->getName(), 'inverse_timestamp' => $won, ), $fname ); - $newid = $dbw->insertId(); $this->mTitle->resetArticleID( $newid ); Article::onArticleCreate( $this->mTitle ); @@ -874,34 +777,55 @@ class Article { # The talk page isn't in the regular link tables, so we need to update manually: $talkns = $ns ^ 1; # talk -> normal; normal -> talk - $dbw->update( 'cur', array('cur_touched' => $dbw->timestamp($now) ), - array( 'cur_namespace' => $talkns, 'cur_title' => $ttl ), $fname ); + $dbw->update( 'page', + array( 'page_touched' => $dbw->timestamp($now) ), + array( 'page_namespace' => $talkns, + 'page_title' => $ttl ), + $fname ); # standard deferred updates - $this->editUpdates( $text ); + $this->editUpdates( $text, $summary, $isminor, $now ); - $this->showArticle( $text, wfMsg( 'newarticle' ) ); + $oldid = 0; # new article + $this->showArticle( $text, wfMsg( 'newarticle' ), false, $isminor, $now, $summary, $oldid ); } - /** - * Side effects: loads last edit if $edittime is NULL + * Fetch and uncompress the text for a given revision. + * Can ask by rev_id number or timestamp (set $field) */ + function fetchRevisionText( $revId = null, $field = 'rev_id' ) { + $fname = 'Article::fetchRevisionText'; + $dbw =& wfGetDB( DB_MASTER ); + if( $revId ) { + $rev = $dbw->addQuotes( $revId ); + } else { + $rev = 'page_latest'; + } + $result = $dbw->query( + sprintf( "SELECT old_text, old_flags + FROM %s,%s,%s + WHERE old_id=rev_id AND rev_page=page_id AND page_id=%d + AND %s=%s", + $dbw->tableName( 'page' ), + $dbw->tableName( 'revision' ), + $dbw->tableName( 'text' ), + IntVal( $this->mTitle->getArticleId() ), + $field, + $rev ), + $fname ); + $obj = $dbw->fetchObject( $result ); + $dbw->freeResult( $result ); + $oldtext = Revision::getRevisionText( $obj ); + return $oldtext; + } + function getTextOfLastEditWithSectionReplacedOrAdded($section, $text, $summary = '', $edittime = NULL) { $fname = 'Article::getTextOfLastEditWithSectionReplacedOrAdded'; - if(is_null($edittime)) { - $this->loadLastEdit(); - $oldtext = $this->getContent( true ); + if( is_null( $edittime ) ) { + $oldtext = $this->fetchRevisionText(); } else { - $dbw =& wfGetDB( DB_MASTER ); - $ns = $this->mTitle->getNamespace(); - $title = $this->mTitle->getDBkey(); - $obj = $dbw->selectRow( 'old', - array( 'old_text','old_flags'), - array( 'old_namespace' => $ns, 'old_title' => $title, - 'old_timestamp' => $dbw->timestamp($edittime)), - $fname ); - $oldtext = Article::getRevisionText( $obj ); + $oldtext = $this->fetchRevisionText( $edittime, 'rev_timestamp' ); } if ($section != '') { if($section=='new') { @@ -1026,22 +950,47 @@ class Article { $now = wfTimestampNow(); $won = wfInvertTimestamp( $now ); - # First update the cur row - $dbw->update( 'cur', - array( /* SET */ - 'cur_text' => $text, - 'cur_comment' => $summary, - 'cur_minor_edit' => $me2, - 'cur_user' => $wgUser->getID(), - 'cur_timestamp' => $dbw->timestamp($now), - 'cur_user_text' => $wgUser->getName(), - 'cur_is_redirect' => $redir, - 'cur_is_new' => 0, - 'cur_touched' => $dbw->timestamp($now), + $mungedText = $text; + $flags = Revision::compressRevisionText( $mungedText ); + + $lastRevision = $dbw->selectField( + 'page', 'page_latest', array( 'page_id' => $this->getId() ) ); + + # Record the text to the text table + $old_id = $dbw->nextSequenceValue( 'text_old_id_val' ); + $dbw->insert( 'text', + array( + 'old_id' => $old_id, + 'old_text' => $mungedText, + 'old_flags' => $flags, + ), $fname + ); + $revisionId = $dbw->insertId(); + + # Record the edit in revisions + $dbw->insert( 'revision', + array( + 'rev_id' => $revisionId, + 'rev_page' => $this->getID(), + 'rev_comment' => $summary, + 'rev_minor_edit' => $me2, + 'rev_user' => $wgUser->getID(), + 'rev_user_text' => $wgUser->getName(), + 'rev_timestamp' => $dbw->timestamp( $now ), 'inverse_timestamp' => $won + ), $fname + ); + + # Update page + $dbw->update( 'page', + array( /* SET */ + 'page_latest' => $revisionId, + 'page_touched' => $dbw->timestamp( $now ), + 'page_is_new' => 0, + 'page_is_redirect' => $redir, ), array( /* WHERE */ - 'cur_id' => $this->getID(), - 'cur_timestamp' => $dbw->timestamp($this->getTimestamp()) + 'page_id' => $this->getID(), + 'page_latest' => $lastRevision, # Paranoia ), $fname ); @@ -1049,32 +998,10 @@ class Article { /* Belated edit conflict! Run away!! */ $good = false; } else { - # Now insert the previous revision into old - - # This overwrites $oldtext if revision compression is on - $flags = Article::compressRevisionText( $oldtext ); - - $dbw->insert( 'old', - array( - 'old_id' => $dbw->nextSequenceValue( 'old_old_id_seq' ), - 'old_namespace' => $this->mTitle->getNamespace(), - 'old_title' => $this->mTitle->getDBkey(), - 'old_text' => $oldtext, - 'old_comment' => $this->getComment(), - 'old_user' => $this->getUser(), - 'old_user_text' => $this->getUserText(), - 'old_timestamp' => $dbw->timestamp($this->getTimestamp()), - 'old_minor_edit' => $me1, - 'inverse_timestamp' => wfInvertTimestamp( $this->getTimestamp() ), - 'old_flags' => $flags, - ), $fname - ); - - $oldid = $dbw->insertId(); - + # Update recentchanges and purge cache and whatnot $bot = (int)($wgUser->isBot() || $forceBot); RecentChange::notifyEdit( $now, $this->mTitle, $me2, $wgUser, $summary, - $oldid, $this->getTimestamp(), $bot ); + $lastRevision, $this->getTimestamp(), $bot ); Article::onArticleEdit( $this->mTitle ); } } @@ -1094,7 +1021,7 @@ class Article { } } # standard deferred updates - $this->editUpdates( $text ); + $this->editUpdates( $text, $summary, $minor, $now ); $urls = array(); @@ -1117,7 +1044,7 @@ class Article { $u->doUpdate(); } - $this->showArticle( $text, wfMsg( 'updated' ), $sectionanchor ); + $this->showArticle( $text, wfMsg( 'updated' ), $sectionanchor, $me2, $now, $summary, $lastRevision ); } return $good; } @@ -1126,8 +1053,8 @@ class Article { * After we've either updated or inserted the article, update * the link tables and redirect to the new page. */ - function showArticle( $text, $subtitle , $sectionanchor = '' ) { - global $wgOut, $wgUser, $wgLinkCache; + function showArticle( $text, $subtitle , $sectionanchor = '', $me2, $now, $summary, $oldid ) { + global $wgOut, $wgUser, $wgLinkCache, $wgEnotif; $wgLinkCache = new LinkCache(); # Select for update @@ -1149,6 +1076,13 @@ class Article { else $r = ''; $wgOut->redirect( $this->mTitle->getFullURL( $r ).$sectionanchor ); + + # this call would better fit into RecentChange::notifyEdit and RecentChange::notifyNew . + # this will be improved later (to-do) + + include_once( "UserMailer.php" ); + $wgEnotif = new EmailNotification (); + $wgEnotif->NotifyOnPageChange( $wgUser->getID(), $this->mTitle->getDBkey(), $this->mTitle->getNamespace(),$now, $summary, $me2, $oldid ); } /** @@ -1200,7 +1134,9 @@ class Article { RecentChange::markPatrolled( $rcid ); $wgOut->setPagetitle( wfMsg( 'markedaspatrolled' ) ); $wgOut->addWikiText( wfMsg( 'markedaspatrolledtext' ) ); - $wgOut->returnToMain( true, $this->mTitle->getPrefixedText() ); + + $rcTitle = Title::makeTitle( NS_SPECIAL, 'Recentchanges' ); + $wgOut->returnToMain( false, $rcTitle->getPrefixedText() ); } else { @@ -1210,11 +1146,12 @@ class Article { /** - * Add or remove this page to my watchlist based on value of $add + * Add this page to $wgUser's watchlist */ - function watch( $add = true ) { + + function watch() { + global $wgUser, $wgOut; - global $wgDeferredUpdateList; if ( 0 == $wgUser->getID() ) { $wgOut->errorpage( 'watchnologin', 'watchnologintext' ); @@ -1224,34 +1161,58 @@ class Article { $wgOut->readOnlyPage(); return; } - if( $add ) - $wgUser->addWatch( $this->mTitle ); - else - $wgUser->removeWatch( $this->mTitle ); - $wgOut->setPagetitle( wfMsg( $add ? 'addedwatch' : 'removedwatch' ) ); - $wgOut->setRobotpolicy( 'noindex,follow' ); - - $sk = $wgUser->getSkin() ; - $link = $this->mTitle->getPrefixedText(); + if (wfRunHooks('WatchArticle', $wgUser, $this)) { + + $wgUser->addWatch( $this->mTitle ); + $wgUser->saveSettings(); - if($add) + wfRunHooks('WatchArticleComplete', $wgUser, $this); + + $wgOut->setPagetitle( wfMsg( 'addedwatch' ) ); + $wgOut->setRobotpolicy( 'noindex,follow' ); + + $link = $this->mTitle->getPrefixedText(); $text = wfMsg( 'addedwatchtext', $link ); - else - $text = wfMsg( 'removedwatchtext', $link ); - $wgOut->addWikiText( $text ); - - $up = new UserUpdate(); - array_push( $wgDeferredUpdateList, $up ); - + $wgOut->addWikiText( $text ); + } + $wgOut->returnToMain( true, $this->mTitle->getPrefixedText() ); } /** - * Stop watching a page, it act just like a call to watch(false) + * Stop watching a page */ + function unwatch() { - $this->watch( false ); + + global $wgUser, $wgOut; + + if ( 0 == $wgUser->getID() ) { + $wgOut->errorpage( 'watchnologin', 'watchnologintext' ); + return; + } + if ( wfReadOnly() ) { + $wgOut->readOnlyPage(); + return; + } + + if (wfRunHooks('UnwatchArticle', $wgUser, $this)) { + + $wgUser->removeWatch( $this->mTitle ); + $wgUser->saveSettings(); + + wfRunHooks('UnwatchArticleComplete', $wgUser, $this); + + $wgOut->setPagetitle( wfMsg( 'removedwatch' ) ); + $wgOut->setRobotpolicy( 'noindex,follow' ); + + $link = $this->mTitle->getPrefixedText(); + $text = wfMsg( 'removedwatchtext', $link ); + $wgOut->addWikiText( $text ); + } + + $wgOut->returnToMain( true, $this->mTitle->getPrefixedText() ); } /** @@ -1275,26 +1236,46 @@ class Article { } $confirm = $wgRequest->getBool( 'wpConfirmProtect' ) && $wgRequest->wasPosted(); + $moveonly = $wgRequest->getBool( 'wpMoveOnly' ); $reason = $wgRequest->getText( 'wpReasonProtect' ); if ( $confirm ) { $dbw =& wfGetDB( DB_MASTER ); - $dbw->update( 'cur', + $dbw->update( 'page', array( /* SET */ - 'cur_touched' => $dbw->timestamp(), - 'cur_restrictions' => (string)$limit + 'page_touched' => $dbw->timestamp(), + 'page_restrictions' => (string)$limit ), array( /* WHERE */ - 'cur_id' => $id + 'page_id' => $id ), 'Article::protect' ); - $log = new LogPage( 'protect' ); - if ( $limit === '' ) { + $restrictions = "move=" . $limit; + if( !$moveonly ) { + $restrictions .= ":edit=" . $limit; + } + if (wfRunHooks('ArticleProtect', $this, $wgUser, $limit == 'sysop', $reason, $moveonly)) { + + $dbw =& wfGetDB( DB_MASTER ); + $dbw->update( 'page', + array( /* SET */ + 'page_touched' => $dbw->timestamp(), + 'page_restrictions' => $restrictions + ), array( /* WHERE */ + 'page_id' => $id + ), 'Article::protect' + ); + + wfRunHooks('ArticleProtectComplete', $this, $wgUser, $limit == 'sysop', $reason, $moveonly); + + $log = new LogPage( 'protect' ); + if ( $limit === '' ) { $log->addEntry( 'unprotect', $this->mTitle, $reason ); - } else { + } else { $log->addEntry( 'protect', $this->mTitle, $reason ); + } + $wgOut->redirect( $this->mTitle->getFullURL() ); } - $wgOut->redirect( $this->mTitle->getFullURL() ); return; } else { $reason = htmlspecialchars( wfMsg( 'protectreason' ) ); @@ -1315,6 +1296,7 @@ class Article { $check = ''; $protcom = ''; + $moveonly = ''; if ( $limit === '' ) { $wgOut->setPageTitle( wfMsg( 'confirmunprotect' ) ); @@ -1328,6 +1310,7 @@ class Article { $wgOut->setSubtitle( wfMsg( 'protectsub', $sub ) ); $wgOut->addWikiText( wfMsg( 'confirmprotecttext' ) ); $check = htmlspecialchars( wfMsg( 'confirmprotect' ) ); + $moveonly = htmlspecialchars( wfMsg( 'protectmoveonly' ) ); $protcom = htmlspecialchars( wfMsg( 'protectcomment' ) ); $formaction = $this->mTitle->escapeLocalURL( 'action=protect' . $par ); } @@ -1355,7 +1338,19 @@ class Article { - + " ); + if($moveonly != '') { + $wgOut->AddHTML( " + + + + + + + + " ); + } + $wgOut->addHTML( "   @@ -1415,26 +1410,28 @@ class Article { $dbr =& $this->getDB(); $ns = $this->mTitle->getNamespace(); $title = $this->mTitle->getDBkey(); - $old = $dbr->selectRow( 'old', - array( 'old_text', 'old_flags' ), + $revisions = $dbr->select( array( 'page', 'revision' ), + array( 'rev_id' ), array( - 'old_namespace' => $ns, - 'old_title' => $title, + 'page_namespace' => $ns, + 'page_title' => $title, + 'rev_page = page_id' ), $fname, $this->getSelectOptions( array( 'ORDER BY' => 'inverse_timestamp' ) ) ); - if( $old !== false && !$confirm ) { + if( $dbr->numRows( $revisions ) > 1 && !$confirm ) { $skin=$wgUser->getSkin(); $wgOut->addHTML(''.wfMsg('historywarning')); $wgOut->addHTML( $skin->historyLink() .''); } # Fetch cur_text - $s = $dbr->selectRow( 'cur', - array( 'cur_text' ), + $s = $dbr->selectRow( array( 'page', 'text' ), + array( 'old_text' ), array( - 'cur_namespace' => $ns, - 'cur_title' => $title, + 'page_namespace' => $ns, + 'page_title' => $title, + 'page_latest = old_id' ), $fname, $this->getSelectOptions() ); @@ -1443,11 +1440,11 @@ class Article { #if this is empty, an earlier revision may contain "useful" text $blanked = false; - if($s->cur_text != '') { - $text=$s->cur_text; + if($s->old_text != '') { + $text=$s->old_text; } else { - if($old) { - $text = Article::getRevisionText( $old ); + if($old) { # TODO + $text = Revision::getRevisionText( $old ); $blanked = true; } @@ -1546,22 +1543,26 @@ class Article { $fname = 'Article::doDelete'; wfDebug( $fname."\n" ); - if ( $this->doDeleteArticle( $reason ) ) { - $deleted = $this->mTitle->getPrefixedText(); - - $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) ); - $wgOut->setRobotpolicy( 'noindex,nofollow' ); - - $sk = $wgUser->getSkin(); - $loglink = $sk->makeKnownLink( $wgContLang->getNsText( NS_PROJECT ) . - ':' . wfMsgForContent( 'dellogpage' ), wfMsg( 'deletionlog' ) ); - - $text = wfMsg( 'deletedtext', $deleted, $loglink ); - - $wgOut->addHTML( '

' . $text . "

\n" ); - $wgOut->returnToMain( false ); - } else { - $wgOut->fatalError( wfMsg( 'cannotdelete' ) ); + if (wfRunHooks('ArticleDelete', $this, $wgUser, $reason)) { + if ( $this->doDeleteArticle( $reason ) ) { + $deleted = $this->mTitle->getPrefixedText(); + + $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) ); + $wgOut->setRobotpolicy( 'noindex,nofollow' ); + + $sk = $wgUser->getSkin(); + $loglink = $sk->makeKnownLink( $wgContLang->getNsText( NS_PROJECT ) . + ':' . wfMsgForContent( 'dellogpage' ), + wfMsg( 'deletionlog' ) ); + + $text = wfMsg( 'deletedtext', $deleted, $loglink ); + + $wgOut->addHTML( '

' . $text . "

\n" ); + $wgOut->returnToMain( false ); + wfRunHooks('ArticleDeleteComplete', $this, $wgUser, $reason); + } else { + $wgOut->fatalError( wfMsg( 'cannotdelete' ) ); + } } } @@ -1610,51 +1611,31 @@ class Article { Title::touchArray( $linksTo ); # Move article and history to the "archive" table - $archiveTable = $dbw->tableName( 'archive' ); - $oldTable = $dbw->tableName( 'old' ); - $curTable = $dbw->tableName( 'cur' ); - $recentchangesTable = $dbw->tableName( 'recentchanges' ); - $linksTable = $dbw->tableName( 'links' ); - $brokenlinksTable = $dbw->tableName( 'brokenlinks' ); - - $dbw->insertSelect( 'archive', 'cur', - array( - 'ar_namespace' => 'cur_namespace', - 'ar_title' => 'cur_title', - 'ar_text' => 'cur_text', - 'ar_comment' => 'cur_comment', - 'ar_user' => 'cur_user', - 'ar_user_text' => 'cur_user_text', - 'ar_timestamp' => 'cur_timestamp', - 'ar_minor_edit' => 'cur_minor_edit', - 'ar_flags' => 0, - ), array( - 'cur_namespace' => $ns, - 'cur_title' => $t, - ), $fname - ); - $dbw->insertSelect( 'archive', 'old', + $dbw->insertSelect( 'archive', array( 'page','revision', 'text' ), array( - 'ar_namespace' => 'old_namespace', - 'ar_title' => 'old_title', + 'ar_namespace' => 'page_namespace', + 'ar_title' => 'page_title', 'ar_text' => 'old_text', - 'ar_comment' => 'old_comment', - 'ar_user' => 'old_user', - 'ar_user_text' => 'old_user_text', - 'ar_timestamp' => 'old_timestamp', - 'ar_minor_edit' => 'old_minor_edit', - 'ar_flags' => 'old_flags' + 'ar_comment' => 'rev_comment', + 'ar_user' => 'rev_user', + 'ar_user_text' => 'rev_user_text', + 'ar_timestamp' => 'rev_timestamp', + 'ar_minor_edit' => 'rev_minor_edit', + 'ar_flags' => 0, ), array( - 'old_namespace' => $ns, - 'old_title' => $t, + 'page_namespace' => $ns, + 'page_title' => $t, + 'page_id = rev_page AND old_id = rev_id' ), $fname ); # Now that it's safely backed up, delete it - $dbw->delete( 'cur', array( 'cur_namespace' => $ns, 'cur_title' => $t ), $fname ); - $dbw->delete( 'old', array( 'old_namespace' => $ns, 'old_title' => $t ), $fname ); + $dbw->deleteJoin( 'text', 'revision', 'old_id', 'rev_id', array( "rev_page = {$id}" ), $fname ); + $dbw->delete( 'revision', array( 'rev_page' => $id ), $fname ); + $dbw->delete( 'page', array( 'page_id' => $id ), $fname); + $dbw->delete( 'recentchanges', array( 'rc_namespace' => $ns, 'rc_title' => $t ), $fname ); # Finally, clean up the link tables @@ -1713,9 +1694,9 @@ class Article { $n = $this->mTitle->getNamespace(); # Get the last editor, lock table exclusively - $s = $dbw->selectRow( 'cur', - array( 'cur_id','cur_user','cur_user_text','cur_comment' ), - array( 'cur_title' => $tt, 'cur_namespace' => $n ), + $s = $dbw->selectRow( array( 'page', 'revision' ), + array( 'page_id','rev_user','rev_user_text','rev_comment' ), + array( 'page_title' => $tt, 'page_namespace' => $n ), $fname, 'FOR UPDATE' ); if( $s === false ) { @@ -1724,20 +1705,20 @@ class Article { return; } $ut = $dbw->strencode( $s->cur_user_text ); - $uid = $s->cur_user; - $pid = $s->cur_id; + $uid = $s->rev_user; + $pid = $s->page_id; $from = str_replace( '_', ' ', $wgRequest->getVal( 'from' ) ); - if( $from != $s->cur_user_text ) { + if( $from != $s->rev_user_text ) { $wgOut->setPageTitle(wfmsg('rollbackfailed')); $wgOut->addWikiText( wfMsg( 'alreadyrolled', htmlspecialchars( $this->mTitle->getPrefixedText()), htmlspecialchars( $from ), - htmlspecialchars( $s->cur_user_text ) ) ); - if($s->cur_comment != '') { + htmlspecialchars( $s->rev_user_text ) ) ); + if($s->rev_comment != '') { $wgOut->addHTML( wfMsg('editcomment', - htmlspecialchars( $s->cur_comment ) ) ); + htmlspecialchars( $s->rev_comment ) ) ); } return; } @@ -1775,7 +1756,7 @@ class Article { $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) ); $wgOut->setRobotpolicy( 'noindex,nofollow' ); $wgOut->addHTML( '

' . htmlspecialchars( $newcomment ) . "

\n
\n" ); - $this->updateArticle( Article::getRevisionText( $s ), $newcomment, 1, $this->mTitle->userIsWatching(), $bot ); + $this->updateArticle( Revision::getRevisionText( $s ), $newcomment, 1, $this->mTitle->userIsWatching(), $bot ); Article::onArticleEdit( $this->mTitle ); $wgOut->returnToMain( false ); } @@ -1787,6 +1768,7 @@ class Article { */ function viewUpdates() { global $wgDeferredUpdateList; + if ( 0 != $this->getID() ) { global $wgDisableCounters; if( !$wgDisableCounters ) { @@ -1795,9 +1777,16 @@ class Article { array_push( $wgDeferredUpdateList, $u ); } } - $u = new UserTalkUpdate( 0, $this->mTitle->getNamespace(), - $this->mTitle->getDBkey() ); - array_push( $wgDeferredUpdateList, $u ); + + # Update newtalk status if user is reading their own + # talk page + + global $wgUser; + if ($this->mTitle->getNamespace() == NS_USER_TALK && + $this->mTitle->getText() == $wgUser->getName()) { + require_once( 'UserTalkUpdate.php' ); + $u = new UserTalkUpdate( 0, $this->mTitle->getNamespace(), $this->mTitle->getDBkey(), false, false, false ); + } } /** @@ -1806,15 +1795,18 @@ class Article { * @private * @param string $text */ - function editUpdates( $text ) { + function editUpdates( $text, $summary, $minoredit, $timestamp_of_pagechange) { global $wgDeferredUpdateList, $wgDBname, $wgMemc; - global $wgMessageCache; + global $wgMessageCache, $wgUser; wfSeedRandom(); if ( 0 == mt_rand( 0, 999 ) ) { + # Periodically flush old entries from the recentchanges table. + global $wgRCMaxAge; $dbw =& wfGetDB( DB_MASTER ); - $cutoff = $dbw->timestamp( time() - ( 7 * 86400 ) ); - $sql = "DELETE FROM recentchanges WHERE rc_timestamp < '{$cutoff}'"; + $cutoff = $dbw->timestamp( time() - $wgRCMaxAge ); + $recentchanges = $dbw->tableName( 'recentchanges' ); + $sql = "DELETE FROM $recentchanges WHERE rc_timestamp < '{$cutoff}'"; $dbw->query( $sql ); } $id = $this->getID(); @@ -1831,8 +1823,14 @@ class Article { $u = new SearchUpdate( $id, $title, $text ); array_push( $wgDeferredUpdateList, $u ); - $u = new UserTalkUpdate( 1, $this->mTitle->getNamespace(), $shortTitle ); - array_push( $wgDeferredUpdateList, $u ); + # If this is another user's talk page, + # create a watchlist entry for this page + + if ($this->mTitle->getNamespace() == NS_USER_TALK && + $shortTitle != $wgUser->getName()) { + require_once( 'UserTalkUpdate.php' ); + $u = new UserTalkUpdate( 1, $this->mTitle->getNamespace(), $shortTitle, $summary, $minoredit, $timestamp_of_pagechange); + } if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) { $wgMessageCache->replace( $shortTitle, $text ); @@ -1884,11 +1882,6 @@ class Article { $called = true; if($this->isFileCacheable()) { $touched = $this->mTouched; - if( $this->mTitle->getPrefixedDBkey() == wfMsg( 'mainpage' ) ) { - # Expire the main page quicker - $expire = wfUnix2Timestamp( time() - 3600 ); - $touched = max( $expire, $touched ); - } $cache = new CacheManager( $this->mTitle ); if($cache->isFileCacheGood( $touched )) { global $wgOut; @@ -1934,11 +1927,11 @@ class Article { $fname = 'Article::checkTouched'; $id = $this->getID(); $dbr =& $this->getDB(); - $s = $dbr->selectRow( 'cur', array( 'cur_touched', 'cur_is_redirect' ), - array( 'cur_id' => $id ), $fname, $this->getSelectOptions() ); + $s = $dbr->selectRow( 'page', array( 'page_touched', 'page_is_redirect' ), + array( 'page_id' => $id ), $fname, $this->getSelectOptions() ); if( $s !== false ) { - $this->mTouched = wfTimestamp(TS_MW,$s->cur_touched); - return !$s->cur_is_redirect; + $this->mTouched = wfTimestamp( TS_MW, $s->page_touched ); + return !$s->page_is_redirect; } else { return false; } @@ -1954,6 +1947,9 @@ class Article { function quickEdit( $text, $comment = '', $minor = 0 ) { global $wgUser; $fname = 'Article::quickEdit'; + + #wfDebugDieBacktrace( "$fname called." ); + wfProfileIn( $fname ); $dbw =& wfGetDB( DB_MASTER ); @@ -1961,52 +1957,33 @@ class Article { $dbkey = $this->mTitle->getDBkey(); $encDbKey = $dbw->strencode( $dbkey ); $timestamp = wfTimestampNow(); - - # Save to history - $dbw->insertSelect( 'old', 'cur', - array( - 'old_namespace' => 'cur_namespace', - 'old_title' => 'cur_title', - 'old_text' => 'cur_text', - 'old_comment' => 'cur_comment', - 'old_user' => 'cur_user', - 'old_user_text' => 'cur_user_text', - 'old_timestamp' => 'cur_timestamp', - 'inverse_timestamp' => '99999999999999-cur_timestamp', - ), array( - 'cur_namespace' => $ns, - 'cur_title' => $dbkey, - ), $fname - ); - - # Use the affected row count to determine if the article is new - $numRows = $dbw->affectedRows(); - - # Make an array of fields to be inserted - $fields = array( - 'cur_text' => $text, - 'cur_timestamp' => $timestamp, - 'cur_user' => $wgUser->getID(), - 'cur_user_text' => $wgUser->getName(), + # insert new text + $dbw->insert( 'text', array( + 'old_text' => $text, + 'old_flags' => "" ), $fname ); + $text_id = $dbw->insertID(); + + # update page + $dbw->update( 'page', array( + 'page_is_new' => 0, + 'page_touched' => $timestamp, + 'page_is_redirect' => $this->isRedirect( $text ) ? 1 : 0, + 'page_latest' => $text_id ), + array( 'page_namespace' => $ns, 'page_title' => $dbkey ), $fname ); + # Retrieve page ID + $page_id = $dbw->selectField( 'page', 'page_id', array( 'page_namespace' => $ns, 'page_title' => $dbkey ), $fname ); + + # update revision + $dbw->insert( 'revision', array( + 'rev_id' => $text_id, + 'rev_page' => $page_id, + 'rev_comment' => $comment, + 'rev_user' => $wgUser->getID(), + 'rev_user_text' => $wgUser->getName(), + 'rev_timestamp' => $timestamp, 'inverse_timestamp' => wfInvertTimestamp( $timestamp ), - 'cur_comment' => $comment, - 'cur_is_redirect' => $this->isRedirect( $text ) ? 1 : 0, - 'cur_minor_edit' => intval($minor), - 'cur_touched' => $dbw->timestamp($timestamp), - ); - - if ( $numRows ) { - # Update article - $fields['cur_is_new'] = 0; - $dbw->update( 'cur', $fields, array( 'cur_namespace' => $ns, 'cur_title' => $dbkey ), $fname ); - } else { - # Insert new article - $fields['cur_is_new'] = 1; - $fields['cur_namespace'] = $ns; - $fields['cur_title'] = $dbkey; - $fields['cur_random'] = $rand = wfRandom(); - $dbw->insert( 'cur', $fields, $fname ); - } + 'rev_minor_edit' => intval($minor) ), + $fname ); wfProfileOut( $fname ); } @@ -2021,12 +1998,12 @@ class Article { global $wgHitcounterUpdateFreq; $dbw =& wfGetDB( DB_MASTER ); - $curTable = $dbw->tableName( 'cur' ); + $pageTable = $dbw->tableName( 'page' ); $hitcounterTable = $dbw->tableName( 'hitcounter' ); $acchitsTable = $dbw->tableName( 'acchits' ); if( $wgHitcounterUpdateFreq <= 1 ){ // - $dbw->query( "UPDATE $curTable SET cur_counter = cur_counter + 1 WHERE cur_id = $id" ); + $dbw->query( "UPDATE $pageTable SET page_counter = page_counter + 1 WHERE page_id = $id" ); return; } @@ -2111,6 +2088,8 @@ class Article { global $wgUser, $wgTitle, $wgOut, $wgAllowPageInfo; $fname = 'Article::info'; +wfDebugDieBacktrace( 'This function is apparently not called by any other PHP file and might be obsolete.' ); + if ( !$wgAllowPageInfo ) { $wgOut->errorpage( 'nosuchaction', 'nosuchactiontext' ); return; @@ -2179,4 +2158,32 @@ class Article { } } +/** + * Check whether an article is a stub + * + * @public + * @param integer $articleID ID of the article that is to be checked + */ +function wfArticleIsStub( $articleID ) { + global $wgUser; + $fname = 'wfArticleIsStub'; + + wfDebugDieBacktrace( 'This function seems to be unused. Pending removal.' ); + + $threshold = $wgUser->getOption('stubthreshold') ; + if ( $threshold > 0 ) { + $dbr =& wfGetDB( DB_SLAVE ); + $s = $dbr->selectRow( array('page', 'text'), + array( 'LENGTH(old_text) AS len', 'page_namespace', 'page_is_redirect' ), + array( 'page_id' => $articleID, "page.page_latest=text.old_id" ), + $fname ) ; + if ( $s == false OR $s->page_is_redirect OR $s->page_namespace != NS_MAIN ) { + return false; + } + $size = $s->len; + return ( $size < $threshold ); + } + return false; +} + ?>