X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2FRevision.php;h=243c9c06a047711c785e5a9ae3894669bbbdf825;hb=41ac01dfc839b4f1c32a354fe37ed064b8a31585;hp=5145033682d7530ae89c17db30df4407c6f57808;hpb=7d3bd1482241553266d4c3cb7ea91f685c3e1bb2;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Revision.php b/includes/Revision.php index 5145033682..243c9c06a0 100644 --- a/includes/Revision.php +++ b/includes/Revision.php @@ -25,7 +25,7 @@ class Revision { public static function newFromId( $id ) { return Revision::newFromConds( array( 'page_id=rev_page', - 'rev_id' => intval( $id ) ) ); + 'rev_id' => intval( $id ) ) ); } /** @@ -34,13 +34,13 @@ class Revision { * to that title, will return null. * * @param $title Title - * @param $id Integer + * @param $id Integer (optional) * @return Revision or null */ public static function newFromTitle( $title, $id = 0 ) { - $conds = array( - 'page_namespace' => $title->getNamespace(), - 'page_title' => $title->getDBkey() + $conds = array( + 'page_namespace' => $title->getNamespace(), + 'page_title' => $title->getDBkey() ); if ( $id ) { // Use the specified ID @@ -50,8 +50,7 @@ class Revision { $dbw = wfGetDB( DB_MASTER ); $latest = $dbw->selectField( 'page', 'page_latest', $conds, __METHOD__ ); if ( $latest === false ) { - // Page does not exist - return null; + return null; // page does not exist } $conds['rev_id'] = $latest; } else { @@ -62,14 +61,47 @@ class Revision { return Revision::newFromConds( $conds ); } + /** + * Load either the current, or a specified, revision + * that's attached to a given page ID. + * Returns null if no such revision can be found. + * + * @param $revId Integer + * @param $pageId Integer (optional) + * @return Revision or null + */ + public static function newFromPageId( $pageId, $revId = 0 ) { + $conds = array( 'page_id' => $pageId ); + if ( $revId ) { + $conds['rev_id'] = $revId; + } elseif ( wfGetLB()->getServerCount() > 1 ) { + // Get the latest revision ID from the master + $dbw = wfGetDB( DB_MASTER ); + $latest = $dbw->selectField( 'page', 'page_latest', $conds, __METHOD__ ); + if ( $latest === false ) { + return null; // page does not exist + } + $conds['rev_id'] = $latest; + } else { + $conds[] = 'rev_id = page_latest'; + } + $conds[] = 'page_id=rev_page'; + return Revision::newFromConds( $conds ); + } + /** * Make a fake revision object from an archive table row. This is queried * for permissions or even inserted (as in Special:Undelete) - * @todo Fixme: should be a subclass for RevisionDelete. [TS] + * @todo FIXME: Should be a subclass for RevisionDelete. [TS] + * + * @param $row + * @param $overrides array + * + * @return Revision */ public static function newFromArchiveRow( $row, $overrides = array() ) { $attribs = $overrides + array( - 'page' => isset( $row->page_id ) ? $row->page_id : null, + 'page' => isset( $row->ar_page_id ) ? $row->ar_page_id : null, 'id' => isset( $row->ar_rev_id ) ? $row->ar_rev_id : null, 'comment' => $row->ar_comment, 'user' => $row->ar_user, @@ -82,10 +114,23 @@ class Revision { if ( isset( $row->ar_text ) && !$row->ar_text_id ) { // Pre-1.5 ar_text row $attribs['text'] = self::getRevisionText( $row, 'ar_' ); + if ( $attribs['text'] === false ) { + throw new MWException( 'Unable to load text from archive row (possibly bug 22624)' ); + } } return new self( $attribs ); } + /** + * @since 1.19 + * + * @param $row + * @return Revision + */ + public static function newFromRow( $row ) { + return new self( $row ); + } + /** * Load a page revision from a given revision ID number. * Returns null if no such revision can be found. @@ -97,7 +142,7 @@ class Revision { public static function loadFromId( $db, $id ) { return Revision::loadFromConds( $db, array( 'page_id=rev_page', - 'rev_id' => intval( $id ) ) ); + 'rev_id' => intval( $id ) ) ); } /** @@ -120,6 +165,30 @@ class Revision { return Revision::loadFromConds( $db, $conds ); } + /** + * Stores the origin wiki of a revision in case it is a foreign wiki + */ + function setWikiID( $wikiID ) { + $this->mWikiID = $wikiID; + } + + /** + * Load the current revision of a given page of a foreign wiki. + * The WikiID is stored for further use, such as loadText() and getTimestampFromId() + */ + public static function loadFromTitleForeignWiki( $wikiID, $title ) { + $dbr = wfGetDB( DB_SLAVE, array(), $wikiID ); + + $revision = self::loadFromTitle( $dbr, $title ); + + if( $revision ) { + $revision->setWikiID( $wikiID ); + } + + return $revision; + + } + /** * Load either the current, or a specified, revision * that's attached to a given page. If not attached @@ -139,9 +208,9 @@ class Revision { return Revision::loadFromConds( $db, array( "rev_id=$matchId", - 'page_id=rev_page', - 'page_namespace' => $title->getNamespace(), - 'page_title' => $title->getDBkey() ) ); + 'page_id=rev_page', + 'page_namespace' => $title->getNamespace(), + 'page_title' => $title->getDBkey() ) ); } /** @@ -149,7 +218,7 @@ class Revision { * WARNING: Timestamps may in some circumstances not be unique, * so this isn't the best key to use. * - * @param $db Database + * @param $db DatabaseBase * @param $title Title * @param $timestamp String * @return Revision or null @@ -158,9 +227,9 @@ class Revision { return Revision::loadFromConds( $db, array( 'rev_timestamp' => $db->timestamp( $timestamp ), - 'page_id=rev_page', - 'page_namespace' => $title->getNamespace(), - 'page_title' => $title->getDBkey() ) ); + 'page_id=rev_page', + 'page_namespace' => $title->getNamespace(), + 'page_title' => $title->getDBkey() ) ); } /** @@ -183,7 +252,7 @@ class Revision { * Given a set of conditions, fetch a revision from * the given database connection. * - * @param $db Database + * @param $db DatabaseBase * @param $conditions Array * @return Revision or null */ @@ -213,9 +282,9 @@ class Revision { return Revision::fetchFromConds( wfGetDB( DB_SLAVE ), array( 'rev_id=page_latest', - 'page_namespace' => $title->getNamespace(), - 'page_title' => $title->getDBkey(), - 'page_id=rev_page' ) ); + 'page_namespace' => $title->getNamespace(), + 'page_title' => $title->getDBkey(), + 'page_id=rev_page' ) ); } /** @@ -223,7 +292,7 @@ class Revision { * which will return matching database rows with the * fields necessary to build Revision objects. * - * @param $db Database + * @param $db DatabaseBase * @param $conditions Array * @return ResultWrapper */ @@ -232,21 +301,19 @@ class Revision { $fields[] = 'page_namespace'; $fields[] = 'page_title'; $fields[] = 'page_latest'; - $res = $db->select( + return $db->select( array( 'page', 'revision' ), $fields, $conditions, __METHOD__, array( 'LIMIT' => 1 ) ); - $ret = $db->resultObject( $res ); - return $ret; } /** * Return the list of revision fields that should be selected to create * a new revision. */ - static function selectFields() { + public static function selectFields() { return array( 'rev_id', 'rev_page', @@ -261,9 +328,9 @@ class Revision { 'rev_parent_id' ); } - + /** - * Return the list of text fields that should be selected to read the + * Return the list of text fields that should be selected to read the * revision text */ static function selectTextFields() { @@ -302,19 +369,20 @@ class Revision { $this->mTimestamp = $row->rev_timestamp; $this->mDeleted = intval( $row->rev_deleted ); - if( !isset( $row->rev_parent_id ) ) + if( !isset( $row->rev_parent_id ) ) { $this->mParentId = is_null($row->rev_parent_id) ? null : 0; - else + } else { $this->mParentId = intval( $row->rev_parent_id ); + } - if( !isset( $row->rev_len ) || is_null( $row->rev_len ) ) + if( !isset( $row->rev_len ) || is_null( $row->rev_len ) ) { $this->mSize = null; - else + } else { $this->mSize = intval( $row->rev_len ); + } if( isset( $row->page_latest ) ) { $this->mCurrent = ( $row->rev_id == $row->page_latest ); - $row->page_id = $this->mPage; $this->mTitle = Title::newFromRow( $row ); } else { $this->mCurrent = false; @@ -358,6 +426,7 @@ class Revision { throw new MWException( 'Revision constructor passed invalid row format.' ); } $this->mUnpatrolled = null; + $this->mWikiID = false; } /** @@ -405,16 +474,16 @@ class Revision { if( isset( $this->mTitle ) ) { return $this->mTitle; } - $dbr = wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); + $row = $dbr->selectRow( array( 'page', 'revision' ), array( 'page_namespace', 'page_title' ), array( 'page_id=rev_page', - 'rev_id' => $this->mId ), + 'rev_id' => $this->mId ), 'Revision::getTitle' ); if( $row ) { - $this->mTitle = Title::makeTitle( $row->page_namespace, - $row->page_title ); + $this->mTitle = Title::makeTitle( $row->page_namespace, $row->page_title ); } return $this->mTitle; } @@ -439,7 +508,7 @@ class Revision { /** * Fetch revision's user id if it's available to the specified audience. - * If the specified audience does not have access to it, zero will be + * If the specified audience does not have access to it, zero will be * returned. * * @param $audience Integer: one of: @@ -471,7 +540,7 @@ class Revision { /** * Fetch revision's username if it's available to the specified audience. - * If the specified audience does not have access to the username, an + * If the specified audience does not have access to the username, an * empty string will be returned. * * @param $audience Integer: one of: @@ -502,7 +571,7 @@ class Revision { /** * Fetch revision comment if it's available to the specified audience. - * If the specified audience does not have access to the comment, an + * If the specified audience does not have access to the comment, an * empty string will be returned. * * @param $audience Integer: one of: @@ -537,7 +606,7 @@ class Revision { public function isMinor() { return (bool)$this->mMinorEdit; } - + /** * @return Integer rcid of the unpatrolled row, zero if there isn't one */ @@ -545,7 +614,7 @@ class Revision { if( $this->mUnpatrolled !== null ) { return $this->mUnpatrolled; } - $dbr = wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); $this->mUnpatrolled = $dbr->selectField( 'recentchanges', 'rc_id', array( // Add redundant user,timestamp condition so we can use the existing index @@ -560,7 +629,7 @@ class Revision { } /** - * int $field one of DELETED_* bitfield constants + * @param $field int one of DELETED_* bitfield constants * * @return Boolean */ @@ -570,6 +639,8 @@ class Revision { /** * Get the deletion bitfield of the revision + * + * @return int */ public function getVisibility() { return (int)$this->mDeleted; @@ -577,7 +648,7 @@ class Revision { /** * Fetch revision text if it's available to the specified audience. - * If the specified audience does not have the ability to view this + * If the specified audience does not have the ability to view this * revision, an empty string will be returned. * * @param $audience Integer: one of: @@ -585,7 +656,6 @@ class Revision { * Revision::FOR_THIS_USER to be displayed to $wgUser * Revision::RAW get the text regardless of permissions * - * * @return String */ public function getText( $audience = self::FOR_PUBLIC ) { @@ -601,10 +671,11 @@ class Revision { /** * Alias for getText(Revision::FOR_THIS_USER) * - * @deprecated + * @deprecated since 1.17 * @return String */ public function revText() { + wfDeprecated( __METHOD__ ); return $this->getText( self::FOR_THIS_USER ); } @@ -722,8 +793,8 @@ class Revision { # Use external methods for external objects, text in table is URL-only then if ( in_array( 'external', $flags ) ) { $url = $text; - @list(/* $proto */, $path ) = explode( '://', $url, 2 ); - if( $path == '' ) { + $parts = explode( '://', $url, 2 ); + if( count( $parts ) == 1 || $parts[1] == '' ) { wfProfileOut( __METHOD__ ); return false; } @@ -751,15 +822,15 @@ class Revision { } global $wgLegacyEncoding; - if( $text !== false && $wgLegacyEncoding - && !in_array( 'utf-8', $flags ) && !in_array( 'utf8', $flags ) ) + if( $text !== false && $wgLegacyEncoding + && !in_array( 'utf-8', $flags ) && !in_array( 'utf8', $flags ) ) { # Old revisions kept around in a legacy encoding? # Upconvert on demand. # ("utf8" checked for compatibility with some broken # conversion scripts 2008-12-30) - global $wgInputEncoding, $wgContLang; - $text = $wgContLang->iconv( $wgLegacyEncoding, $wgInputEncoding, $text ); + global $wgContLang; + $text = $wgContLang->iconv( $wgLegacyEncoding, 'UTF-8', $text ); } } wfProfileOut( __METHOD__ ); @@ -799,7 +870,7 @@ class Revision { * Insert a new revision into the database, returning the new revision ID * number on success and dies horribly on failure. * - * @param $dbw DatabaseBase (master connection) + * @param $dbw DatabaseBase: (master connection) * @return Integer */ public function insertOn( $dbw ) { @@ -879,7 +950,11 @@ class Revision { // Caching may be beneficial for massive use of external storage global $wgRevisionCacheExpiry, $wgMemc; $textId = $this->getTextId(); + if( isset( $this->mWikiID ) && $this->mWikiID !== false ) { + $key = wfForeignMemcKey( $this->mWikiID, null, 'revisiontext', 'textid', $textId ); + } else { $key = wfMemcKey( 'revisiontext', 'textid', $textId ); + } if( $wgRevisionCacheExpiry ) { $text = $wgMemc->get( $key ); if( is_string( $text ) ) { @@ -899,7 +974,7 @@ class Revision { if( !$row ) { // Text data is immutable; check slaves first. - $dbr = wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); $row = $dbr->selectRow( 'text', array( 'old_text', 'old_flags' ), array( 'old_id' => $this->getTextId() ), @@ -908,7 +983,7 @@ class Revision { if( !$row && wfGetLB()->getServerCount() > 1 ) { // Possible slave lag! - $dbw = wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER, array(), $this->mWikiID ); $row = $dbw->selectRow( 'text', array( 'old_text', 'old_flags' ), array( 'old_id' => $this->getTextId() ), @@ -939,7 +1014,7 @@ class Revision { * @param $pageId Integer: ID number of the page to read from * @param $summary String: revision's summary * @param $minor Boolean: whether the revision should be considered as minor - * @return Mixed: Revision, or null on error + * @return Revision|null on error */ public static function newNullRevision( $dbw, $pageId, $summary, $minor ) { wfProfileIn( __METHOD__ ); @@ -997,7 +1072,6 @@ class Revision { public static function userCanBitfield( $bitfield, $field ) { if( $bitfield & $field ) { // aspect is deleted global $wgUser; - $permission = ''; if ( $bitfield & self::DELETED_RESTRICTED ) { $permission = 'suppressrevision'; } elseif ( $field & self::DELETED_TEXT ) { @@ -1020,7 +1094,8 @@ class Revision { * @return String */ static function getTimestampFromId( $title, $id ) { - $dbr = wfGetDB( DB_SLAVE ); + $wikiId = wfWikiID(); + $dbr = wfGetDB( DB_SLAVE, array(), $wikiId ); // Casting fix for DB2 if ( $id == '' ) { $id = 0; @@ -1030,7 +1105,7 @@ class Revision { $timestamp = $dbr->selectField( 'revision', 'rev_timestamp', $conds, __METHOD__ ); if ( $timestamp === false && wfGetLB()->getServerCount() > 1 ) { # Not in slave, try master - $dbw = wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER, array(), $wikiId ); $timestamp = $dbw->selectField( 'revision', 'rev_timestamp', $conds, __METHOD__ ); } return wfTimestamp( TS_MW, $timestamp ); @@ -1067,11 +1142,3 @@ class Revision { return 0; } } - -/** - * Aliases for backwards compatibility with 1.6 - */ -define( 'MW_REV_DELETED_TEXT', Revision::DELETED_TEXT ); -define( 'MW_REV_DELETED_COMMENT', Revision::DELETED_COMMENT ); -define( 'MW_REV_DELETED_USER', Revision::DELETED_USER ); -define( 'MW_REV_DELETED_RESTRICTED', Revision::DELETED_RESTRICTED );