var $mRedirect = null; // /< Is the article at this title a redirect?
var $mNotificationTimestamp = array(); // /< Associative array of user ID -> timestamp/false
var $mBacklinkCache = null; // /< Cache of links to this title
+ var $mHasSubpage; // /< Whether a page has any subpages
// @}
* fied by a prefix. If you want to force a specific namespace even if
* $text might begin with a namespace prefix, use makeTitle() or
* makeTitleSafe().
- * @return Title, or null on an error.
+ * @throws MWException
+ * @return Title|null - Title or null on an error.
*/
public static function newFromText( $text, $defaultNamespace = NS_MAIN ) {
if ( is_object( $text ) ) {
* @return Title the new object, or NULL on an error
*/
public static function newFromURL( $url ) {
- global $wgLegalTitleChars;
$t = new Title();
# For compatibility with old buggy URLs. "+" is usually not valid in titles,
# but some URLs used it as a space replacement and they still come
# from some external search tools.
- if ( strpos( $wgLegalTitleChars, '+' ) === false ) {
+ if ( strpos( self::legalChars(), '+' ) === false ) {
$url = str_replace( '+', ' ', $url );
}
* 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
- * @return void
+ * @param $row Object|bool database row
*/
public function loadFromRow( $row ) {
if ( $row ) { // page found
* @return Title the new object, or NULL on an error
*/
public static function makeTitleSafe( $ns, $title, $fragment = '', $interwiki = '' ) {
+ if ( !MWNamespace::exists( $ns ) ) {
+ return null;
+ }
+
$t = new Title();
$t->mDbkeyform = Title::makeName( $ns, $title, $fragment, $interwiki );
if ( $t->secureAndSplit() ) {
}
}
- // Strip off subpages
- $pagename = $this->getText();
- if ( strpos( $pagename, '/' ) !== false ) {
- list( $username , ) = explode( '/', $pagename, 2 );
- } else {
- $username = $pagename;
- }
-
if ( $wgContLang->needsGenderDistinction() &&
MWNamespace::hasGenderDistinction( $this->mNamespace ) ) {
- $gender = GenderCache::singleton()->getGenderOf( $username, __METHOD__ );
+ $gender = GenderCache::singleton()->getGenderOf( $this->getText(), __METHOD__ );
return $wgContLang->getGenderNsText( $this->mNamespace, $gender );
}
* 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
+ * @param $ns int
+ * @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)
+ * @param $query
+ * @param $query2 bool
+ * @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 getLocalURL for the arguments.
*
* @see self::getLocalURL
+ * @param $query string
+ * @param $query2 bool|string
* @return String the URL
*/
public function escapeLocalURL( $query = '', $query2 = false ) {
*
* @see self::getLocalURL
* @since 1.18
+ * @return string
*/
public function escapeCanonicalURL( $query = '', $query2 = false ) {
wfDeprecated( __METHOD__, '1.19' );
// 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 );
$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 ) ) {
- # Check for explicit whitelisting
$whitelisted = true;
} elseif ( $this->getNamespace() == NS_MAIN ) {
# Old settings might have the title prefixed with
/**
* Get the expiry time for the restriction against a given action
*
+ * @param $action
* @return String|Bool 14-char timestamp, or 'infinity' if the page is protected forever
- * or not protected at all, or false if the action is not recognised.
+ * or not protected at all, or false if the action is not recognised.
*/
public function getRestrictionExpiry( $action ) {
if ( !$this->mRestrictionsLoaded ) {
if ( $oldFashionedRestrictions === null ) {
$oldFashionedRestrictions = $dbr->selectField( 'page', 'page_restrictions',
- array( 'page_id' => $this->getArticleId() ), __METHOD__ );
+ array( 'page_id' => $this->getArticleID() ), __METHOD__ );
}
if ( $oldFashionedRestrictions != '' ) {
$res = $dbr->select(
'page_restrictions',
'*',
- array( 'pr_page' => $this->getArticleId() ),
+ array( 'pr_page' => $this->getArticleID() ),
__METHOD__
);
* @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;
*/
public function getPreviousRevisionID( $revId, $flags = 0 ) {
$db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
- return $db->selectField( 'revision', 'rev_id',
+ $revId = $db->selectField( 'revision', 'rev_id',
array(
- 'rev_page' => $this->getArticleId( $flags ),
+ 'rev_page' => $this->getArticleID( $flags ),
'rev_id < ' . intval( $revId )
),
__METHOD__,
array( 'ORDER BY' => 'rev_id DESC' )
);
+
+ if ( $revId === false ) {
+ return false;
+ } else {
+ return intval( $revId );
+ }
}
/**
*/
public function getNextRevisionID( $revId, $flags = 0 ) {
$db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
- return $db->selectField( 'revision', 'rev_id',
+ $revId = $db->selectField( 'revision', 'rev_id',
array(
- 'rev_page' => $this->getArticleId( $flags ),
+ 'rev_page' => $this->getArticleID( $flags ),
'rev_id > ' . intval( $revId )
),
__METHOD__,
array( 'ORDER BY' => 'rev_id' )
);
+
+ if ( $revId === false ) {
+ return false;
+ } else {
+ return intval( $revId );
+ }
}
/**
* @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', '*',
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
*/
$dbr = wfGetDB( DB_SLAVE );
$this->mNotificationTimestamp[$uid] = $dbr->selectField( 'watchlist',
'wl_notificationtimestamp',
- array( 'wl_namespace' => $this->getNamespace(),
+ array(
+ 'wl_user' => $user->getId(),
+ 'wl_namespace' => $this->getNamespace(),
'wl_title' => $this->getDBkey(),
- 'wl_user' => $user->getId()
),
__METHOD__
);
* $wgLang (such as special pages, which are in the user language).
*
* @since 1.18
- * @return object Language
+ * @return Language
*/
public function getPageLanguage() {
global $wgLang;
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 ) {