/**
* Used to be GAID_FOR_UPDATE define. Used with getArticleID() and friends
- * to SELECT FOR UPDATE
+ * to use the master DB
*/
const GAID_FOR_UPDATE = 1;
- /**
- * Used with getArticleID() and friends to load the object from the master
- * database
- */
- const GAID_USE_MASTER = 2;
-
- /**
- * For use in load(). Field is available in LinkCache.
- */
- const FIELD_IN_LINKCACHE = 1;
-
- /**
- * For use in load(). Field is not available in LinkCache.
- */
- const FIELD_NOT_IN_LINKCACHE = 2;
-
/**
* @name Private member variables
* Please use the accessor functions instead.
var $mNamespace = NS_MAIN; // /< Namespace index, i.e. one of the NS_xxxx constants
var $mInterwiki = ''; // /< Interwiki prefix (or null string)
var $mFragment; // /< Title fragment (i.e. the bit after the #)
- private $mLoadedLevel = 0; // /<
- private $mLoadedFromMaster = false;
var $mArticleID = -1; // /< Article ID, fetched from the link cache on demand
var $mLatestID = false; // /< ID of most recent revision
- private $mCounter = false; // /< Number of times this page has been viewed (-1 means "not loaded")
- private $mTouched; // /< Timestamp of the last time this page was touched
- private $mIsNew; // /< Whether this is a "new page" (i.e. it has only one revision)
private $mEstimateRevisions; // /< Estimated number of revisions; null of not loaded
var $mRestrictions = array(); // /< Array of groups allowed to edit this article
- var $mOldRestrictions;
+ var $mOldRestrictions = false;
var $mCascadeRestriction; ///< Cascade restrictions on this page to included templates and images?
var $mCascadingRestrictions; // Caching the results of getCascadeProtectionSources
var $mRestrictionsExpiry = array(); ///< When do the restrictions on this page expire?
* Create a new Title from an article ID
*
* @param $id Int the page_id corresponding to the Title to create
- * @param $flags Int use Title::GAID_USE_MASTER to use master
+ * @param $flags Int use Title::GAID_FOR_UPDATE to use master
* @return Title the new object, or NULL on an error
*/
public static function newFromID( $id, $flags = 0 ) {
- $db = $flags ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
$row = $db->selectRow( 'page', '*', array( 'page_id' => $id ), __METHOD__ );
if ( $row !== false ) {
$title = Title::newFromRow( $row );
}
$dbr = wfGetDB( DB_SLAVE );
- $res = $dbr->select( 'page', self::selectFields(),
- array( 'page_id' => $ids ), __METHOD__ );
+ $res = $dbr->select(
+ 'page',
+ array(
+ 'page_namespace', 'page_title', 'page_id',
+ 'page_len', 'page_is_redirect', 'page_latest',
+ ),
+ array( 'page_id' => $ids ),
+ __METHOD__
+ );
$titles = array();
foreach ( $res as $row ) {
* Load Title object fields from a DB row.
* If false is given, the title will be treated as non-existing.
*
- * @param $row Object|false database row
- * @param $wasFromMaster bool: whether the row was loaded from the master
- * database
- * @return void
+ * @param $row Object|bool database row
*/
- public function loadFromRow( $row, $wasFromMaster = false ) {
+ public function loadFromRow( $row ) {
if ( $row ) { // page found
- $cacheLevel = self::FIELD_NOT_IN_LINKCACHE;
-
- # Items that cannot be stored in LinkCache
- # If one (or more) of these field is missing, the row can still
- # be stored in LinkCache
- if ( isset( $row->page_counter ) ) {
- $this->mCounter = (int)$row->page_counter;
- } else {
- $cacheLevel = self::FIELD_IN_LINKCACHE;
- }
- if ( isset( $row->page_touched ) ) {
- $this->mTouched = $row->page_touched;
- } else {
- $cacheLevel = self::FIELD_IN_LINKCACHE;
- }
- if ( isset( $row->page_is_new ) ) {
- $this->mIsNew = (bool)$row->page_is_new;
- } else {
- $cacheLevel = self::FIELD_IN_LINKCACHE;
- }
- if ( isset( $row->page_restrictions ) ) {
- $this->mOldRestrictions = $row->page_restrictions;
- } else {
- $cacheLevel = self::FIELD_IN_LINKCACHE;
- }
-
- # Items that can be stored in LinkCache
- # If one (or more) of these field is missing, the row cannot
- # be stored in LinkCache
- if ( isset( $row->page_id ) ) {
+ if ( isset( $row->page_id ) )
$this->mArticleID = (int)$row->page_id;
- } else {
- $cacheLevel = 0;
- }
- if ( isset( $row->page_len ) ) {
+ if ( isset( $row->page_len ) )
$this->mLength = (int)$row->page_len;
- } else {
- $cacheLevel = 0;
- }
- if ( isset( $row->page_is_redirect ) ) {
+ if ( isset( $row->page_is_redirect ) )
$this->mRedirect = (bool)$row->page_is_redirect;
- } else {
- $cacheLevel = 0;
- }
- if ( isset( $row->page_latest ) ) {
+ if ( isset( $row->page_latest ) )
$this->mLatestID = (int)$row->page_latest;
- } else {
- $cacheLevel = 0;
- }
-
- $this->mLoadedLevel = $cacheLevel;
- if ( $cacheLevel > 0 ) {
- # We have all fields required by LinkCache
- LinkCache::singleton()->addGoodLinkObjFromRow( $this, $row );
- }
} else { // page not found
$this->mArticleID = 0;
$this->mLength = 0;
$this->mRedirect = false;
$this->mLatestID = 0;
- $this->mCounter = 0;
- $this->mTouched = '19700101000000';
- $this->mIsNew = false;
- $this->mOldRestrictions = false;
- $this->mLoadedLevel = 2;
- LinkCache::singleton()->addBadLinkObj( $this );
}
- $this->mLoadedFromMaster = $wasFromMaster;
}
/**
return $n;
}
- /**
- * Get the fields of the `page` table that have to be select if you want
- * to give a complete row to loadFromRow()
- *
- * @return array
- */
- public static function selectFields() {
- return array(
- 'page_namespace',
- 'page_title',
- 'page_id',
- 'page_len',
- 'page_is_redirect',
- 'page_latest',
- 'page_counter',
- 'page_touched',
- 'page_is_new',
- 'page_restrictions',
- );
- }
-
/**
* Get a regex character class describing the legal characters in a link
*
* This is MUCH simpler than individually testing for equivilance
* against both NS_USER and NS_USER_TALK, and is also forward compatible.
* @since 1.19
+ * @return bool
*/
public function hasSubjectNamespace( $ns ) {
return MWNamespace::subjectEquals( $this->getNamespace(), $ns );
/**
* Helper to fix up the get{Local,Full,Link,Canonical}URL args
+ * get{Canonical,Full,Link,Local}URL methods accepted an optional
+ * second argument named variant. This was deprecated in favor
+ * of passing an array of option with a "variant" key
+ * Once $query2 is removed for good, this helper can be dropped
+ * andthe wfArrayToCGI moved to getLocalURL();
+ *
+ * @since 1.19 (r105919)
+ * @return String
*/
- private static function fixUrlQueryArgs( $query, $query2 ) {
+ private static function fixUrlQueryArgs( $query, $query2 = false ) {
+ if( $query2 !== false ) {
+ wfDeprecated( "Title::get{Canonical,Full,Link,Local} method called with a second parameter is deprecated. Add your parameter to an array passed as the first parameter.", "1.19" );
+ }
if ( is_array( $query ) ) {
$query = wfArrayToCGI( $query );
}
* with action=render, $wgServer is prepended.
*
- * @param $query \twotypes{\string,\array} an optional query string,
+ * @param $query string|array an optional query string,
* not used for interwiki links. Can be specified as an associative array as well,
* e.g., array( 'action' => 'edit' ) (keys and values will be URL-escaped).
* Some query patterns will trigger various shorturl path replacements.
* be an array. If a string is passed it will be interpreted as a deprecated
* variant argument and urlencoded into a variant= argument.
* This second query argument will be added to the $query
+ * The second parameter is deprecated since 1.19. Pass it as a key,value
+ * pair in the first parameter array instead.
+ *
* @return String the URL
*/
public function getLocalURL( $query = '', $query2 = false ) {
*
* @see self::getLocalURL
* @since 1.18
+ * @return string
*/
public function escapeCanonicalURL( $query = '', $query2 = false ) {
wfDeprecated( __METHOD__, '1.19' );
return $s;
}
- /**
- * Load field from database into this object
- *
- * @param $level int, may be on of the following values:
- * - self::FIELD_IN_LINKCACHE: the field can be retrived from the LinkCache
- * - self::FIELD_NOT_IN_LINKCACHE: the field is not stored in LinkCache and
- * must be loaded from the database
- * @param $flags int, may be on of the following values:
- * - 0: to use a slave connection
- * - self::GAID_USE_MASTER to use a master connection
- * - self::GAID_FOR_UPDATE to SELECT FROM UPDATE from a master connection
- */
- private function load( $level, $flags = 0 ) {
- global $wgAntiLockFlags;
-
- if ( !$this->canExist() ) {
- return;
- }
-
- // Check whether the wanted item is already loaded
- // and from where it is requested.
- // If $flags is self::GAID_FOR_UPDATE, it will always be reloaded.
- if ( $level <= $this->mLoadedLevel && ( $flags === 0 ||
- ( $flags === self::GAID_USE_MASTER && $this->mLoadedFromMaster ) ) )
- {
- return;
- }
-
- $linkCache = LinkCache::singleton();
-
- # Only use the LinkCache if we can load from a slave database
- if ( $flags === 0 ) {
-
- # If the LinkCache says the page doesn't exist; we can load all fields
- if ( $linkCache->isBadLink( $this->getPrefixedDBkey() ) ) {
- $this->loadFromRow( false );
- return;
- }
-
- # For existing pages we can only load some fields
- if ( $level === self::FIELD_IN_LINKCACHE ) {
- $id = $linkCache->getGoodLinkID( $this->getPrefixedDBkey() );
- if ( $id ) {
- $this->mArticleID = $id;
- $this->mRedirect = (bool)$linkCache->getGoodLinkFieldObj( $this, 'redirect' );
- $this->mLength = (int)$linkCache->getGoodLinkFieldObj( $this, 'length' );
- $this->mLatestID = (int)$linkCache->getGoodLinkFieldObj( $this, 'revision' );
- $this->mLoadedLevel = 1;
- $this->mLoadedFromMaster = false;
- return;
- }
- }
- }
-
- # Just in case it's already loaded from a slave database
- $linkCache->clearLink( $this );
-
- # No success using LinkCache, we need to use the database
- # In this case we load the complete row regardless of $level
- $options = array();
- if ( $flags === 0 ) {
- $db = wfGetDB( DB_SLAVE );
- $this->mLoadedFromMaster = false;
- } else {
- $db = wfGetDB( DB_MASTER );
- if ( $flags == self::GAID_FOR_UPDATE && !( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) ) {
- $options[] = 'FOR UPDATE';
- }
- $this->mLoadedFromMaster = true;
- }
-
- $row = $db->selectRow( 'page', self::selectFields(),
- $this->pageCond(), __METHOD__, $options );
- $this->loadFromRow( $row );
- }
-
/**
* Is $wgUser watching this page?
*
// Don't block the user from editing their own talk page unless they've been
// explicitly blocked from that too.
} elseif( $user->isBlocked() && $user->mBlock->prevents( $action ) !== false ) {
- $block = $user->mBlock;
+ $block = $user->getBlock();
// This is from OutputPage::blockedPage
// Copied at r23888 by werdna
$link = '[[' . $wgContLang->getNsText( NS_USER ) . ":{$name}|{$name}]]";
$blockid = $block->getId();
- $blockExpiry = $user->mBlock->mExpiry;
- $blockTimestamp = $wgLang->timeanddate( wfTimestamp( TS_MW, $user->mBlock->mTimestamp ), true );
+ $blockExpiry = $block->getExpiry();
+ $blockTimestamp = $wgLang->timeanddate( wfTimestamp( TS_MW, $block->mTimestamp ), true );
if ( $blockExpiry == 'infinity' ) {
$blockExpiry = wfMessage( 'infiniteblock' )->text();
} else {
$blockExpiry = $wgLang->timeanddate( wfTimestamp( TS_MW, $blockExpiry ), true );
}
- $intended = strval( $user->mBlock->getTarget() );
+ $intended = strval( $block->getTarget() );
$errors[] = array( ( $block->mAuto ? 'autoblockedtext' : 'blockedtext' ), $link, $reason, $ip, $name,
$blockid, $blockExpiry, $intended, $blockTimestamp );
* @return Array list of errors
*/
private function checkReadPermissions( $action, $user, $errors, $doExpensiveQueries, $short ) {
+ global $wgWhitelistRead, $wgGroupPermissions, $wgRevokePermissions;
static $useShortcut = null;
# Initialize the $useShortcut boolean, to determine if we can skip quite a bit of code below
if ( is_null( $useShortcut ) ) {
- global $wgGroupPermissions, $wgRevokePermissions;
$useShortcut = true;
if ( empty( $wgGroupPermissions['*']['read'] ) ) {
# Not a public wiki, so no shortcut
}
}
- # Shortcut for public wikis, allows skipping quite a bit of code
+ $whitelisted = false;
if ( $useShortcut ) {
- return $errors;
- }
-
- # If the user is allowed to read pages, he is allowed to read all pages
- if ( $user->isAllowed( 'read' ) ) {
- return $errors;
- }
-
- # Always grant access to the login page.
- # Even anons need to be able to log in.
- if ( $this->isSpecial( 'Userlogin' )
+ # Shortcut for public wikis, allows skipping quite a bit of code
+ $whitelisted = true;
+ } elseif ( $user->isAllowed( 'read' ) ) {
+ # If the user is allowed to read pages, he is allowed to read all pages
+ $whitelisted = true;
+ } elseif ( $this->isSpecial( 'Userlogin' )
|| $this->isSpecial( 'ChangePassword' )
|| $this->isSpecial( 'PasswordReset' )
) {
- return $errors;
- }
-
- # Time to check the whitelist
- global $wgWhitelistRead;
-
- # Only do these checks is there's something to check against
- if ( is_array( $wgWhitelistRead ) && count( $wgWhitelistRead ) ) {
- # Check for explicit whitelisting
+ # Always grant access to the login page.
+ # Even anons need to be able to log in.
+ $whitelisted = true;
+ } elseif ( is_array( $wgWhitelistRead ) && count( $wgWhitelistRead ) ) {
+ # Time to check the whitelist
+ # Only do these checks is there's something to check against
$name = $this->getPrefixedText();
$dbName = $this->getPrefixedDBKey();
- // Check with and without underscores
+ // Check for explicit whitelisting with and without underscores
if ( in_array( $name, $wgWhitelistRead, true ) || in_array( $dbName, $wgWhitelistRead, true ) ) {
- return $errors;
- }
-
- # Old settings might have the title prefixed with
- # a colon for main-namespace pages
- if ( $this->getNamespace() == NS_MAIN ) {
+ $whitelisted = true;
+ } elseif ( $this->getNamespace() == NS_MAIN ) {
+ # Old settings might have the title prefixed with
+ # a colon for main-namespace pages
if ( in_array( ':' . $name, $wgWhitelistRead ) ) {
- return $errors;
+ $whitelisted = true;
}
- }
-
- # If it's a special page, ditch the subpage bit and check again
- if ( $this->isSpecialPage() ) {
+ } elseif ( $this->isSpecialPage() ) {
+ # If it's a special page, ditch the subpage bit and check again
$name = $this->getDBkey();
list( $name, /* $subpage */ ) = SpecialPageFactory::resolveAlias( $name );
if ( $name !== false ) {
$pure = SpecialPage::getTitleFor( $name )->getPrefixedText();
if ( in_array( $pure, $wgWhitelistRead, true ) ) {
- return $errors;
+ $whitelisted = true;
}
}
}
}
- $errors[] = $this->missingPermissionError( $action, $short );
+ if ( !$whitelisted ) {
+ # If the title is not whitelisted, give extensions a chance to do so...
+ wfRunHooks( 'TitleReadWhitelist', array( $this, $user, &$whitelisted ) );
+ if ( !$whitelisted ) {
+ $errors[] = $this->missingPermissionError( $action, $short );
+ }
+ }
+
return $errors;
}
* Loads a string into mRestrictions array
*
* @param $res Resource restrictions as an SQL result.
+ * @param $oldFashionedRestrictions String comma-separated list of page
+ * restrictions from page table (pre 1.10)
*/
- private function loadRestrictionsFromResultWrapper( $res ) {
+ private function loadRestrictionsFromResultWrapper( $res, $oldFashionedRestrictions = null ) {
$rows = array();
foreach ( $res as $row ) {
$rows[] = $row;
}
- $this->loadRestrictionsFromRows( $rows );
+ $this->loadRestrictionsFromRows( $rows, $oldFashionedRestrictions );
}
/**
* Public for usage by LiquidThreads.
*
* @param $rows array of db result objects
+ * @param $oldFashionedRestrictions string comma-separated list of page
+ * restrictions from page table (pre 1.10)
*/
- public function loadRestrictionsFromRows( $rows ) {
+ public function loadRestrictionsFromRows( $rows, $oldFashionedRestrictions = null ) {
global $wgContLang;
$dbr = wfGetDB( DB_SLAVE );
# Backwards-compatibility: also load the restrictions from the page record (old format).
- if ( $this->mOldRestrictions === null ) {
- $this->mOldRestrictions = $dbr->selectField( 'page', 'page_restrictions',
- array( 'page_id' => $this->getArticleId() ), __METHOD__ );
+ if ( $oldFashionedRestrictions === null ) {
+ $oldFashionedRestrictions = $dbr->selectField( 'page', 'page_restrictions',
+ array( 'page_id' => $this->getArticleID() ), __METHOD__ );
}
- if ( $this->mOldRestrictions !== false && $this->mOldRestrictions !== '' ) {
- foreach ( explode( ':', trim( $this->mOldRestrictions ) ) as $restrict ) {
+ if ( $oldFashionedRestrictions != '' ) {
+
+ foreach ( explode( ':', trim( $oldFashionedRestrictions ) ) as $restrict ) {
$temp = explode( '=', trim( $restrict ) );
if ( count( $temp ) == 1 ) {
// old old format should be treated as edit/move restriction
$this->mRestrictions[$temp[0]] = explode( ',', trim( $temp[1] ) );
}
}
+
+ $this->mOldRestrictions = true;
+
}
if ( count( $rows ) ) {
/**
* Load restrictions from the page_restrictions table
+ *
+ * @param $oldFashionedRestrictions String comma-separated list of page
+ * restrictions from page table (pre 1.10)
*/
- public function loadRestrictions() {
+ public function loadRestrictions( $oldFashionedRestrictions = null ) {
global $wgContLang;
if ( !$this->mRestrictionsLoaded ) {
if ( $this->exists() ) {
$res = $dbr->select(
'page_restrictions',
'*',
- array( 'pr_page' => $this->getArticleId() ),
+ array( 'pr_page' => $this->getArticleID() ),
__METHOD__
);
- $this->loadRestrictionsFromResultWrapper( $res );
+ $this->loadRestrictionsFromResultWrapper( $res, $oldFashionedRestrictions );
} else {
$title_protection = $this->getTitleProtection();
}
/**
- * Get the number of views of this page
- *
- * @return int The view count for the page
- */
- public function getCount() {
- if ( $this->mCounter == false ) {
- $this->load( self::FIELD_NOT_IN_LINKCACHE );
- }
-
- return $this->mCounter;
- }
-
- /**
- * Get the last touched timestamp
+ * Get the article ID for this Title from the link cache,
+ * adding it if necessary
*
- * @return String last-touched timestamp
- */
- public function getTouched() {
- if ( $this->mTouched == null ) {
- $this->load( self::FIELD_NOT_IN_LINKCACHE );
- }
-
- return $this->mTouched;
- }
-
- /**
- * Check if this is a new page (i.e. it has only one revision)
- *
- * @return bool
- */
- public function isNewPage() {
- if ( $this->mIsNew === null ) {
- $this->load( self::FIELD_NOT_IN_LINKCACHE );
- }
-
- return $this->mIsNew;
- }
-
- /**
- * Get the article ID for this page.
- * Uses link cache, adding it if necessary.
- *
- * @param $flags Int a bit field; may be Title::GAID_USE_MASTER to select
- * from the master database or Title::GAID_FOR_UPDATE to select for update.
+ * @param $flags Int a bit field; may be Title::GAID_FOR_UPDATE to select
+ * for update
* @return Int the ID
*/
public function getArticleID( $flags = 0 ) {
- if ( $this->mArticleID === -1 || $flags ) {
- $this->load( self::FIELD_IN_LINKCACHE, $flags );
+ if ( $this->getNamespace() < 0 ) {
+ return $this->mArticleID = 0;
+ }
+ $linkCache = LinkCache::singleton();
+ if ( $flags & self::GAID_FOR_UPDATE ) {
+ $oldUpdate = $linkCache->forUpdate( true );
+ $linkCache->clearLink( $this );
+ $this->mArticleID = $linkCache->addLinkObj( $this );
+ $linkCache->forUpdate( $oldUpdate );
+ } else {
+ if ( -1 == $this->mArticleID ) {
+ $this->mArticleID = $linkCache->addLinkObj( $this );
+ }
}
-
return $this->mArticleID;
}
/**
* Is this an article that is a redirect page?
- * Uses link cache, adding it if necessary.
+ * Uses link cache, adding it if necessary
*
- * @param $flags Int a bit field; may be Title::GAID_USE_MASTER to select
- * from the master database or Title::GAID_FOR_UPDATE to select for update.
+ * @param $flags Int a bit field; may be Title::GAID_FOR_UPDATE to select for update
* @return Bool
*/
public function isRedirect( $flags = 0 ) {
- if ( $this->mRedirect === null || $flags ) {
- $this->load( self::FIELD_IN_LINKCACHE, $flags );
+ if ( !is_null( $this->mRedirect ) ) {
+ return $this->mRedirect;
+ }
+ # Calling getArticleID() loads the field from cache as needed
+ if ( !$this->getArticleID( $flags ) ) {
+ return $this->mRedirect = false;
}
+ $linkCache = LinkCache::singleton();
+ $this->mRedirect = (bool)$linkCache->getGoodLinkFieldObj( $this, 'redirect' );
return $this->mRedirect;
}
/**
* What is the length of this page?
- * Uses link cache, adding it if necessary.
+ * Uses link cache, adding it if necessary
*
- * @param $flags Int a bit field; may be Title::GAID_USE_MASTER to select
- * from the master database or Title::GAID_FOR_UPDATE to select for update.
+ * @param $flags Int a bit field; may be Title::GAID_FOR_UPDATE to select for update
* @return Int
*/
public function getLength( $flags = 0 ) {
- if ( $this->mLength === -1 || $flags ) {
- $this->load( self::FIELD_IN_LINKCACHE, $flags );
+ if ( $this->mLength != -1 ) {
+ return $this->mLength;
}
+ # Calling getArticleID() loads the field from cache as needed
+ if ( !$this->getArticleID( $flags ) ) {
+ return $this->mLength = 0;
+ }
+ $linkCache = LinkCache::singleton();
+ $this->mLength = intval( $linkCache->getGoodLinkFieldObj( $this, 'length' ) );
return $this->mLength;
}
/**
* What is the page_latest field for this page?
*
- * @param $flags Int a bit field; may be Title::GAID_USE_MASTER to select
- * from the master database or Title::GAID_FOR_UPDATE to select for update.
+ * @param $flags Int a bit field; may be Title::GAID_FOR_UPDATE to select for update
* @return Int or 0 if the page doesn't exist
*/
public function getLatestRevID( $flags = 0 ) {
- if ( $this->mLatestID === false || $flags ) {
- $this->load( self::FIELD_IN_LINKCACHE, $flags );
+ if ( $this->mLatestID !== false ) {
+ return intval( $this->mLatestID );
+ }
+ # Calling getArticleID() loads the field from cache as needed
+ if ( !$this->getArticleID( $flags ) ) {
+ return $this->mLatestID = 0;
}
+ $linkCache = LinkCache::singleton();
+ $this->mLatestID = intval( $linkCache->getGoodLinkFieldObj( $this, 'revision' ) );
return $this->mLatestID;
}
* @param $newid Int the new Article ID
*/
public function resetArticleID( $newid ) {
- LinkCache::singleton()->clearLink( $this );
+ $linkCache = LinkCache::singleton();
+ $linkCache->clearLink( $this );
- if ( $newid === 0 ) {
- $this->loadFromRow( false );
+ if ( $newid === false ) {
+ $this->mArticleID = -1;
} else {
- if ( $newid === false ) {
- $this->mArticleID = -1;
- } else {
- $this->mArticleID = intval( $newid );
- }
- $this->mRestrictionsLoaded = false;
- $this->mRestrictions = array();
- $this->mOldRestrictions = null;
- $this->mRedirect = null;
- $this->mLength = -1;
- $this->mLatestID = false;
- $this->mCounter = false;
- $this->mTouched = '19700101000000';
- $this->mIsNew = null;
- $this->mEstimateRevisions = null;
- $this->mLoadedLevel = 0;
- $this->mLoadedFromMaster = false;
+ $this->mArticleID = intval( $newid );
}
+ $this->mRestrictionsLoaded = false;
+ $this->mRestrictions = array();
+ $this->mRedirect = null;
+ $this->mLength = -1;
+ $this->mLatestID = false;
+ $this->mEstimateRevisions = null;
}
/**
* @return Array of Title objects linking here
*/
public function getLinksFrom( $options = array(), $table = 'pagelinks', $prefix = 'pl' ) {
- $id = $this->getArticleId();
+ $id = $this->getArticleID();
# If the page doesn't exist; there can't be any link from this page
if ( !$id ) {
* @return Array of Title the Title objects
*/
public function getBrokenLinksFrom() {
- if ( $this->getArticleId() == 0 ) {
+ if ( $this->getArticleID() == 0 ) {
# All links from article ID 0 are false positives
return array();
}
array( 'page', 'pagelinks' ),
array( 'pl_namespace', 'pl_title' ),
array(
- 'pl_from' => $this->getArticleId(),
+ 'pl_from' => $this->getArticleID(),
'page_namespace IS NULL'
),
__METHOD__, array(),
RepoGroup::singleton()->clearCache( $nt ); # clear false negative cache
}
- $dbw->begin(); # If $file was a LocalFile, its transaction would have closed our own.
+ $dbw->begin( __METHOD__ ); # If $file was a LocalFile, its transaction would have closed our own.
$pageid = $this->getArticleID( self::GAID_FOR_UPDATE );
$protected = $this->isProtected();
$err = $this->moveToInternal( $nt, $reason, $createRedirect );
if ( is_array( $err ) ) {
# @todo FIXME: What about the File we have already moved?
- $dbw->rollback();
+ $dbw->rollback( __METHOD__ );
return $err;
}
WatchedItem::duplicateEntries( $this, $nt );
}
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
wfRunHooks( 'TitleMoveComplete', array( &$this, &$nt, &$wgUser, $pageid, $redirid ) );
return true;
$comment = $wgContLang->truncate( $comment, 255 );
$oldid = $this->getArticleID();
- $latest = $this->getLatestRevID();
$dbw = wfGetDB( DB_MASTER );
$newpage->updateRevisionOn( $dbw, $nullRevision );
wfRunHooks( 'NewRevisionFromEditComplete',
- array( $newpage, $nullRevision, $latest, $wgUser ) );
+ array( $newpage, $nullRevision, $nullRevision->getParentId(), $wgUser ) );
$newpage->doEditUpdates( $nullRevision, $wgUser, array( 'changed' => false ) );
+ if ( !$moveOverRedirect ) {
+ WikiPage::onArticleCreate( $nt );
+ }
+
# Recreate the redirect, this time in the other direction.
if ( $redirectSuppressed ) {
WikiPage::onArticleDelete( $this );
// We don't know whether this function was called before
// or after moving the root page, so check both
// $this and $nt
- if ( $oldSubpage->getArticleId() == $this->getArticleId() ||
- $oldSubpage->getArticleID() == $nt->getArticleId() )
+ if ( $oldSubpage->getArticleID() == $this->getArticleID() ||
+ $oldSubpage->getArticleID() == $nt->getArticleID() )
{
// When moving a page to a subpage of itself,
// don't move it twice
$data = array();
- $titleKey = $this->getArticleId();
+ $titleKey = $this->getArticleID();
if ( $titleKey === 0 ) {
return $data;
$db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
return $db->selectField( 'revision', 'rev_id',
array(
- 'rev_page' => $this->getArticleId( $flags ),
+ 'rev_page' => $this->getArticleID( $flags ),
'rev_id < ' . intval( $revId )
),
__METHOD__,
$db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
return $db->selectField( 'revision', 'rev_id',
array(
- 'rev_page' => $this->getArticleId( $flags ),
+ 'rev_page' => $this->getArticleID( $flags ),
'rev_id > ' . intval( $revId )
),
__METHOD__,
* @return Revision|Null if page doesn't exist
*/
public function getFirstRevision( $flags = 0 ) {
- $pageId = $this->getArticleId( $flags );
+ $pageId = $this->getArticleID( $flags );
if ( $pageId ) {
$db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
$row = $db->selectRow( 'revision', '*',
return $rev ? $rev->getTimestamp() : null;
}
+ /**
+ * Check if this is a new page
+ *
+ * @return bool
+ */
+ public function isNewPage() {
+ $dbr = wfGetDB( DB_SLAVE );
+ return (bool)$dbr->selectField( 'page', 'page_is_new', $this->pageCond(), __METHOD__ );
+ }
+
/**
* Check whether the number of revisions of this page surpasses $wgDeleteRevisionsLimit
*
if ( $this->mEstimateRevisions === null ) {
$dbr = wfGetDB( DB_SLAVE );
$this->mEstimateRevisions = $dbr->estimateRowCount( 'revision', '*',
- array( 'rev_page' => $this->getArticleId() ), __METHOD__ );
+ array( 'rev_page' => $this->getArticleID() ), __METHOD__ );
}
return $this->mEstimateRevisions;
$dbr = wfGetDB( DB_SLAVE );
return (int)$dbr->selectField( 'revision', 'count(*)',
array(
- 'rev_page' => $this->getArticleId(),
+ 'rev_page' => $this->getArticleID(),
'rev_timestamp > ' . $dbr->addQuotes( $dbr->timestamp( $old->getTimestamp() ) ),
'rev_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( $new->getTimestamp() ) )
),
* @return Bool
*/
public function exists() {
- return $this->getArticleId() != 0;
+ return $this->getArticleID() != 0;
}
/**
* @return Bool
*/
public function isAlwaysKnown() {
+ $isKnown = null;
+
+ /**
+ * Allows overriding default behaviour for determining if a page exists.
+ * If $isKnown is kept as null, regular checks happen. If it's
+ * a boolean, this value is returned by the isKnown method.
+ *
+ * @since 1.20
+ *
+ * @param Title $title
+ * @param boolean|null $isKnown
+ */
+ wfRunHooks( 'TitleIsAlwaysKnown', array( $this, &$isKnown ) );
+
+ if ( !is_null( $isKnown ) ) {
+ return $isKnown;
+ }
+
if ( $this->mInterwiki != '' ) {
return true; // any interwiki link might be viewable, for all we know
}
+
switch( $this->mNamespace ) {
case NS_MEDIA:
case NS_FILE:
* viewed? In particular, this function may be used to determine if
* links to the title should be rendered as "bluelinks" (as opposed to
* "redlinks" to non-existent pages).
+ * Adding something else to this function will cause inconsistency
+ * since LinkHolderArray calls isAlwaysKnown() and does its own
+ * page existence check.
*
* @return Bool
*/
}
}
+ /**
+ * Get the last touched timestamp
+ *
+ * @param $db DatabaseBase: optional db
+ * @return String last-touched timestamp
+ */
+ public function getTouched( $db = null ) {
+ $db = isset( $db ) ? $db : wfGetDB( DB_SLAVE );
+ $touched = $db->selectField( 'page', 'page_touched', $this->pageCond(), __METHOD__ );
+ return $touched;
+ }
+
/**
* Get the timestamp when this page was updated since the user last saw it.
*
if ( $this->isSpecialPage() ) {
// special pages are in the user language
return $wgLang;
- } elseif ( $this->isCssOrJsPage() ) {
+ } elseif ( $this->isCssOrJsPage() || $this->isCssJsSubpage() ) {
// css/js should always be LTR and is, in fact, English
return wfGetLangObj( 'en' );
} elseif ( $this->getNamespace() == NS_MEDIAWIKI ) {