require_once( dirname( __FILE__ ) . '/normal/UtfNormal.php' );
}
-define ( 'GAID_FOR_UPDATE', 1 );
+/**
+ * @deprecated This used to be a define, but was moved to
+ * Title::GAID_FOR_UPDATE in 1.17. This will probably be removed in 1.18
+ */
+define( 'GAID_FOR_UPDATE', Title::GAID_FOR_UPDATE );
/**
* Represents a title within MediaWiki.
*/
const CACHE_MAX = 1000;
+ /**
+ * Used to be GAID_FOR_UPDATE define. Used with getArticleId() and friends
+ * to use the master DB
+ */
+ const GAID_FOR_UPDATE = 1;
+
/**
* @name Private member variables
}
/**
- * Convert things like é ā or 〗 into normalized(bug 14952) text
+ * Convert things like é ā or 〗 into normalized (bug 14952) text
*/
$filteredText = Sanitizer::decodeCharReferencesAndNormalize( $text );
* Create a new Title from an article ID
*
* @param $id \type{\int} the page_id corresponding to the Title to create
- * @param $flags \type{\int} use GAID_FOR_UPDATE to use master
+ * @param $flags \type{\int} use Title::GAID_FOR_UPDATE to use master
* @return \type{Title} the new object, or NULL on an error
*/
public static function newFromID( $id, $flags = 0 ) {
- $db = ( $flags & GAID_FOR_UPDATE ) ? 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 );
* This will only return the very next target, useful for
* the redirect table and other checks that don't need full recursion
*
- * @param $text \type{\string} Text with possible redirect
- * @return \type{Title} The corresponding Title
+ * @param $text String: Text with possible redirect
+ * @return Title: The corresponding Title
*/
public static function newFromRedirect( $text ) {
return self::newFromRedirectInternal( $text );
/**
* Get the main part with underscores
*
- * @return \type{\string} Main part of the title, with underscores
+ * @return String: Main part of the title, with underscores
*/
public function getDBkey() { return $this->mDbkeyform; }
/**
* Get the namespace index, i.e.\ one of the NS_xxxx constants.
*
- * @return \type{\int} Namespace index
+ * @return Integer: Namespace index
*/
public function getNamespace() { return $this->mNamespace; }
/**
* Get the namespace text
*
- * @return \type{\string} Namespace text
+ * @return String: Namespace text
*/
public function getNsText() {
global $wgContLang;
*/
public function getLocalURL( $query = '', $variant = false ) {
global $wgArticlePath, $wgScript, $wgServer, $wgRequest;
- global $wgVariantArticlePath, $wgContLang, $wgUser;
+ global $wgVariantArticlePath, $wgContLang;
if ( is_array( $query ) ) {
$query = wfArrayToCGI( $query );
}
- // internal links should point to same variant as current page (only anonymous users)
- if ( !$variant && $wgContLang->hasVariants() && !$wgUser->isLoggedIn() ) {
- $pref = $wgContLang->getPreferredVariant( false );
- if ( $pref != $wgContLang->getCode() ) {
- $variant = $pref;
- }
- }
-
if ( $this->isExternal() ) {
$url = $this->getFullURL();
if ( $query ) {
* @return \type{\array} Array of arrays of the arguments to wfMsg to explain permissions problems.
*/
public function getUserPermissionsErrors( $action, $user, $doExpensiveQueries = true, $ignoreErrors = array() ) {
- if ( !StubObject::isRealObject( $user ) ) {
- // Since StubObject is always used on globals, we can
- // unstub $wgUser here and set $user = $wgUser
- global $wgUser;
- $wgUser->_unstub( '', 5 );
- $user = $wgUser;
- }
-
$errors = $this->getUserPermissionsErrorsInternal( $action, $user, $doExpensiveQueries );
// Remove the errors being ignored.
$errors[] = array( 'cant-move-to-user-page' );
}
} elseif ( !$user->isAllowed( $action ) ) {
- $return = null;
-
// We avoid expensive display logic for quickUserCan's and such
$groups = false;
if ( !$short ) {
*/
private function checkPermissionHooks( $action, $user, $errors, $doExpensiveQueries, $short ) {
// Use getUserPermissionsErrors instead
+ $result = '';
if ( !wfRunHooks( 'userCan', array( &$this, &$user, $action, &$result ) ) ) {
return $result ? array() : array( array( 'badaccess-group0' ) );
}
* @see checkQuickPermissions for parameter information
*/
private function checkUserBlock( $action, $user, $errors, $doExpensiveQueries, $short ) {
- if( $short ) {
+ if( $short && count( $errors ) > 0 ) {
return $errors;
}
return $this->mTitleProtection;
}
+ private function invalidateTitleProtectionCache() {
+ unset( $this->mTitleProtection );
+ }
+
/**
* Update the title protection status
*
$dbw->delete( 'protected_titles', array( 'pt_namespace' => $namespace,
'pt_title' => $title ), __METHOD__ );
}
+ $this->invalidateTitleProtectionCache();
+
# Update the protection log
if ( $dbw->affectedRows() ) {
$log = new LogPage( 'protect' );
array( 'pt_namespace' => $this->getNamespace(), 'pt_title' => $this->getDBkey() ),
__METHOD__
);
+ $this->invalidateTitleProtectionCache();
}
/**
}
if ( $purgeExpired ) {
Title::purgeExpiredRestrictions();
+ $this->invalidateTitleProtectionCache();
}
wfProfileOut( __METHOD__ );
*/
private function loadRestrictionsFromResultWrapper( $res, $oldFashionedRestrictions = null ) {
$rows = array();
- $dbr = wfGetDB( DB_SLAVE );
- while ( $row = $dbr->fetchObject( $res ) ) {
+ foreach ( $res as $row ) {
$rows[] = $row;
}
if ( $purgeExpired ) {
Title::purgeExpiredRestrictions();
+ $this->invalidateTitleProtectionCache();
}
}
$this->mRestrictions['create'] = explode( ',', trim( $title_protection['pt_create_perm'] ) );
} else { // Get rid of the old restrictions
Title::purgeExpiredRestrictions();
+ $this->invalidateTitleProtectionCache();
}
} else {
$this->mRestrictionsExpiry['create'] = Block::decodeExpiry( '' );
* Get the article ID for this Title from the link cache,
* adding it if necessary
*
- * @param $flags \type{\int} a bit field; may be GAID_FOR_UPDATE to select
+ * @param $flags \type{\int} a bit field; may be Title::GAID_FOR_UPDATE to select
* for update
* @return \type{\int} the ID
*/
return $this->mArticleID = 0;
}
$linkCache = LinkCache::singleton();
- if ( $flags & GAID_FOR_UPDATE ) {
+ if ( $flags & self::GAID_FOR_UPDATE ) {
$oldUpdate = $linkCache->forUpdate( true );
$linkCache->clearLink( $this );
$this->mArticleID = $linkCache->addLinkObj( $this );
* Is this an article that is a redirect page?
* Uses link cache, adding it if necessary
*
- * @param $flags \type{\int} a bit field; may be GAID_FOR_UPDATE to select for update
+ * @param $flags \type{\int} a bit field; may be Title::GAID_FOR_UPDATE to select for update
* @return \type{\bool}
*/
public function isRedirect( $flags = 0 ) {
* What is the length of this page?
* Uses link cache, adding it if necessary
*
- * @param $flags \type{\int} a bit field; may be GAID_FOR_UPDATE to select for update
+ * @param $flags \type{\int} a bit field; may be Title::GAID_FOR_UPDATE to select for update
* @return \type{\bool}
*/
public function getLength( $flags = 0 ) {
/**
* What is the page_latest field for this page?
*
- * @param $flags \type{\int} a bit field; may be GAID_FOR_UPDATE to select for update
+ * @param $flags \type{\int} a bit field; may be Title::GAID_FOR_UPDATE to select for update
* @return \type{\int} or 0 if the page doesn't exist
*/
public function getLatestRevID( $flags = 0 ) {
* This clears some fields in this object, and clears any associated
* keys in the "bad links" section of the link cache.
*
+ * - This is called from Article::insertNewArticle() to allow
+ * loading of the new page_id. It's also called from
+ * Article::doDeleteArticle()
+ *
* @param $newid \type{\int} the new Article ID
*/
public function resetArticleID( $newid ) {
/**
* Get a Title object associated with the talk page of this article
*
- * @return \type{Title} the object for the talk page
+ * @return Title the object for the talk page
*/
public function getTalkPage() {
return Title::makeTitle( MWNamespace::getTalk( $this->getNamespace() ), $this->getDBkey() );
* Get a title object associated with the subject page of this
* talk page
*
- * @return \type{Title} the object for the subject page
+ * @return Title the object for the subject page
*/
public function getSubjectPage() {
// Is this the same title?
$retVal = array();
if ( $db->numRows( $res ) ) {
foreach ( $res as $row ) {
- if ( $titleObj = Title::makeTitle( $row->page_namespace, $row->page_title ) ) {
+ $titleObj = Title::makeTitle( $row->page_namespace, $row->page_title );
+ if ( $titleObj ) {
$linkCache->addGoodLinkObj( $row->page_id, $titleObj, $row->page_len, $row->page_is_redirect, $row->page_latest );
$retVal[] = $titleObj;
}
}
}
- $db->freeResult( $res );
return $retVal;
}
# Truncate for whole multibyte characters. +5 bytes for ellipsis
$comment = $wgContLang->truncate( $comment, 250 );
- $newid = $nt->getArticleID();
$oldid = $this->getArticleID();
$latest = $this->getLatestRevId();
. " ORDER BY cl_sortkey";
$res = $dbr->query( $sql );
+ $data = array();
if ( $dbr->numRows( $res ) > 0 ) {
- foreach ( $res as $row )
+ foreach ( $res as $row ) {
// $data[] = Title::newFromText($wgContLang->getNSText ( NS_CATEGORY ).':'.$row->cl_to);
$data[$wgContLang->getNSText( NS_CATEGORY ) . ':' . $row->cl_to] = $this->getFullText();
- $dbr->freeResult( $res );
- } else {
- $data = array();
+ }
}
return $data;
}
}
}
}
- return $stack;
- } else {
- return array();
}
+
+ return $stack;
}
* Get the revision ID of the previous revision
*
* @param $revId \type{\int} Revision ID. Get the revision that was before this one.
- * @param $flags \type{\int} GAID_FOR_UPDATE
+ * @param $flags \type{\int} Title::GAID_FOR_UPDATE
* @return \twotypes{\int,\bool} Old revision ID, or FALSE if none exists
*/
public function getPreviousRevisionID( $revId, $flags = 0 ) {
- $db = ( $flags & GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
return $db->selectField( 'revision', 'rev_id',
array(
'rev_page' => $this->getArticleId( $flags ),
* Get the revision ID of the next revision
*
* @param $revId \type{\int} Revision ID. Get the revision that was after this one.
- * @param $flags \type{\int} GAID_FOR_UPDATE
+ * @param $flags \type{\int} Title::GAID_FOR_UPDATE
* @return \twotypes{\int,\bool} Next revision ID, or FALSE if none exists
*/
public function getNextRevisionID( $revId, $flags = 0 ) {
- $db = ( $flags & GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
return $db->selectField( 'revision', 'rev_id',
array(
'rev_page' => $this->getArticleId( $flags ),
/**
* Get the first revision of the page
*
- * @param $flags \type{\int} GAID_FOR_UPDATE
+ * @param $flags \type{\int} Title::GAID_FOR_UPDATE
* @return Revision (or NULL if page doesn't exist)
*/
public function getFirstRevision( $flags = 0 ) {
- $db = ( $flags & GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
$pageId = $this->getArticleId( $flags );
if ( !$pageId ) {
return null;
);
}
+ /**
+ * Get the number of authors between the given revision IDs.
+ * Used for diffs and other things that really need it.
+ *
+ * @param $fromRevId \type{\int} Revision ID (first before range)
+ * @param $toRevId \type{\int} Revision ID (first after range)
+ * @param $limit \type{\int} Maximum number of authors
+ * @param $flags \type{\int} Title::GAID_FOR_UPDATE
+ * @return \type{\int}
+ */
+ public function countAuthorsBetween( $fromRevId, $toRevId, $limit, $flags = 0 ) {
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $res = $db->select( 'revision', 'DISTINCT rev_user_text',
+ array(
+ 'rev_page = ' . $this->getArticleID(),
+ 'rev_id > ' . (int)$fromRevId,
+ 'rev_id < ' . (int)$toRevId
+ ), __METHOD__,
+ array( 'LIMIT' => $limit )
+ );
+ return (int)$db->numRows( $res );
+ }
+
/**
* Compare with another title.
*
return true; // any interwiki link might be viewable, for all we know
}
switch( $this->mNamespace ) {
- case NS_MEDIA:
- case NS_FILE:
- return (bool)wfFindFile( $this ); // file exists, possibly in a foreign repo
- case NS_SPECIAL:
- return SpecialPage::exists( $this->getDBkey() ); // valid special page
- case NS_MAIN:
- return $this->mDbkeyform == ''; // selflink, possibly with fragment
- case NS_MEDIAWIKI:
- // If the page is form Mediawiki:message/lang, calling wfMsgWeirdKey causes
- // the full l10n of that language to be loaded. That takes much memory and
- // isn't needed. So we strip the language part away.
- list( $basename, /* rest */ ) = explode( '/', $this->mDbkeyform, 2 );
- return (bool)wfMsgWeirdKey( $basename ); // known system message
- default:
- return false;
+ case NS_MEDIA:
+ case NS_FILE:
+ return (bool)wfFindFile( $this ); // file exists, possibly in a foreign repo
+ case NS_SPECIAL:
+ return SpecialPage::exists( $this->getDBkey() ); // valid special page
+ case NS_MAIN:
+ return $this->mDbkeyform == ''; // selflink, possibly with fragment
+ case NS_MEDIAWIKI:
+ // If the page is form Mediawiki:message/lang, calling wfMsgWeirdKey causes
+ // the full l10n of that language to be loaded. That takes much memory and
+ // isn't needed. So we strip the language part away.
+ list( $basename, /* rest */ ) = explode( '/', $this->mDbkeyform, 2 );
+ return (bool)wfMsgWeirdKey( $basename ); // known system message
+ default:
+ return false;
}
}
* @return \type{\bool}
*/
public function isKnown() {
- return $this->exists() || $this->isAlwaysKnown();
+ return $this->isAlwaysKnown() || $this->exists();
}
/**
* In other words, is this a content page, for the purposes of calculating
* statistics, etc?
*
- * @return \type{\bool}
+ * @return Boolean
*/
public function isContentPage() {
return MWNamespace::isContent( $this->getNamespace() );
__METHOD__
);
-
foreach ( $res as $row ) {
$redirs[] = self::newFromRow( $row );
}