}
try {
- return Title::newFromTextThrow( strval( $text ), $defaultNamespace );
+ return self::newFromTextThrow( strval( $text ), $defaultNamespace );
} catch ( MalformedTitleException $ex ) {
return null;
}
__METHOD__
);
if ( $row !== false ) {
- $title = Title::newFromRow( $row );
+ $title = self::newFromRow( $row );
} else {
$title = null;
}
$titles = [];
foreach ( $res as $row ) {
- $titles[] = Title::newFromRow( $row );
+ $titles[] = self::newFromRow( $row );
}
return $titles;
}
}
$t = new Title();
- $t->mDbkeyform = Title::makeName( $ns, $title, $fragment, $interwiki, true );
+ $t->mDbkeyform = self::makeName( $ns, $title, $fragment, $interwiki, true );
try {
$t->secureAndSplit();
* @return Title The new object
*/
public static function newMainPage() {
- $title = Title::newFromText( wfMessage( 'mainpage' )->inContentLanguage()->text() );
+ $title = self::newFromText( wfMessage( 'mainpage' )->inContentLanguage()->text() );
// Don't give fatal errors if the message is broken
if ( !$title ) {
- $title = Title::newFromText( 'Main Page' );
+ $title = self::newFromText( 'Main Page' );
}
return $title;
}
*/
public function getContentModel( $flags = 0 ) {
if ( !$this->mForcedContentModel
- && ( !$this->mContentModel || $flags === Title::GAID_FOR_UPDATE )
+ && ( !$this->mContentModel || $flags === self::GAID_FOR_UPDATE )
&& $this->getArticleID( $flags )
) {
$linkCache = LinkCache::singleton();
}
/**
- * Could this title have a corresponding talk page?
+ * Can this title have a corresponding talk page?
*
- * @return bool
+ * @deprecated since 1.30, use canHaveTalkPage() instead.
+ *
+ * @return bool True if this title either is a talk page or can have a talk page associated.
*/
public function canTalk() {
- return MWNamespace::canTalk( $this->mNamespace );
+ return $this->canHaveTalkPage();
+ }
+
+ /**
+ * Can this title have a corresponding talk page?
+ *
+ * @see MWNamespace::hasTalkNamespace
+ *
+ * @return bool True if this title either is a talk page or can have a talk page associated.
+ */
+ public function canHaveTalkPage() {
+ return MWNamespace::hasTalkNamespace( $this->mNamespace );
}
/**
if ( $canonicalName ) {
$localName = SpecialPageFactory::getLocalNameFor( $canonicalName, $par );
if ( $localName != $this->mDbkeyform ) {
- return Title::makeTitle( NS_SPECIAL, $localName );
+ return self::makeTitle( NS_SPECIAL, $localName );
}
}
}
* @return bool
*/
public function isMainPage() {
- return $this->equals( Title::newMainPage() );
+ return $this->equals( self::newMainPage() );
}
/**
* @return Title The object for the talk page
*/
public function getTalkPage() {
- return Title::makeTitle( MWNamespace::getTalk( $this->getNamespace() ), $this->getDBkey() );
+ return self::makeTitle( MWNamespace::getTalk( $this->getNamespace() ), $this->getDBkey() );
}
/**
if ( $this->getNamespace() == $subjectNS ) {
return $this;
}
- return Title::makeTitle( $subjectNS, $this->getDBkey() );
+ return self::makeTitle( $subjectNS, $this->getDBkey() );
}
/**
if ( !$this->hasFragment() ) {
return '';
} else {
- return '#' . Title::escapeFragmentForURL( $this->getFragment() );
+ return '#' . self::escapeFragmentForURL( $this->getFragment() );
}
}
* @return string The prefixed text
*/
private function prefix( $name ) {
+ global $wgContLang;
+
$p = '';
if ( $this->isExternal() ) {
$p = $this->mInterwiki . ':';
}
if ( 0 != $this->mNamespace ) {
- $p .= $this->getNsText() . ':';
+ $nsText = $this->getNsText();
+
+ if ( $nsText === false ) {
+ // See T165149. Awkward, but better than erroneously linking to the main namespace.
+ $nsText = $wgContLang->getNsText( NS_SPECIAL ) . ":Badtitle/NS{$this->mNamespace}";
+ }
+
+ $p .= $nsText . ':';
}
return $p . $name;
}
* @since 1.20
*/
public function getRootTitle() {
- return Title::makeTitle( $this->getNamespace(), $this->getRootText() );
+ return self::makeTitle( $this->getNamespace(), $this->getRootText() );
}
/**
* @since 1.20
*/
public function getBaseTitle() {
- return Title::makeTitle( $this->getNamespace(), $this->getBaseText() );
+ return self::makeTitle( $this->getNamespace(), $this->getBaseText() );
}
/**
* @since 1.20
*/
public function getSubpage( $text ) {
- return Title::makeTitleSafe( $this->getNamespace(), $this->getText() . '/' . $text );
+ return self::makeTitleSafe( $this->getNamespace(), $this->getText() . '/' . $text );
}
/**
$page_id = $row->pr_page;
$page_ns = $row->page_namespace;
$page_title = $row->page_title;
- $sources[$page_id] = Title::makeTitle( $page_ns, $page_title );
+ $sources[$page_id] = self::makeTitle( $page_ns, $page_title );
# Add groups needed for each restriction type if its not already there
# Make sure this restriction type still exists
if ( $limit > -1 ) {
$options['LIMIT'] = $limit;
}
- $this->mSubpages = TitleArray::newFromResult(
+ return TitleArray::newFromResult(
$dbr->select( 'page',
[ 'page_id', 'page_namespace', 'page_title', 'page_is_redirect' ],
$conds,
$options
)
);
- return $this->mSubpages;
}
/**
* @return int Int or 0 if the page doesn't exist
*/
public function getLatestRevID( $flags = 0 ) {
- if ( !( $flags & Title::GAID_FOR_UPDATE ) && $this->mLatestID !== false ) {
+ if ( !( $flags & self::GAID_FOR_UPDATE ) && $this->mLatestID !== false ) {
return intval( $this->mLatestID );
}
if ( !$this->getArticleID( $flags ) ) {
if ( $res->numRows() ) {
$linkCache = LinkCache::singleton();
foreach ( $res as $row ) {
- $titleObj = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $titleObj = self::makeTitle( $row->page_namespace, $row->page_title );
if ( $titleObj ) {
$linkCache->addGoodLinkObjFromRow( $titleObj, $row );
$retVal[] = $titleObj;
$linkCache = LinkCache::singleton();
foreach ( $res as $row ) {
if ( $row->page_id ) {
- $titleObj = Title::newFromRow( $row );
+ $titleObj = self::newFromRow( $row );
} else {
- $titleObj = Title::makeTitle( $row->$blNamespace, $row->$blTitle );
+ $titleObj = self::makeTitle( $row->$blNamespace, $row->$blTitle );
$linkCache->addBadLinkObj( $titleObj );
}
$retVal[] = $titleObj;
$retVal = [];
foreach ( $res as $row ) {
- $retVal[] = Title::makeTitle( $row->pl_namespace, $row->pl_title );
+ $retVal[] = self::makeTitle( $row->pl_namespace, $row->pl_title );
}
return $retVal;
}
* @return array|bool True on success, getUserPermissionsErrors()-like array on failure
*/
public function moveTo( &$nt, $auth = true, $reason = '', $createRedirect = true,
- array $changeTags = [] ) {
-
+ array $changeTags = []
+ ) {
global $wgUser;
$err = $this->isValidMoveOperation( $nt, $auth, $reason );
if ( is_array( $err ) ) {
* no pages were moved
*/
public function moveSubpages( $nt, $auth = true, $reason = '', $createRedirect = true,
- array $changeTags = [] ) {
-
+ array $changeTags = []
+ ) {
global $wgMaximumMovedPages;
// Check permissions
if ( !$this->userCan( 'move-subpages' ) ) {
}
# T16385: we need makeTitleSafe because the new page names may
# be longer than 255 characters.
- $newSubpage = Title::makeTitleSafe( $newNs, $newPageName );
+ $newSubpage = self::makeTitleSafe( $newNs, $newPageName );
$success = $oldSubpage->moveTo( $newSubpage, $auth, $reason, $createRedirect, $changeTags );
if ( $success === true ) {
# Circular reference
$stack[$parent] = [];
} else {
- $nt = Title::newFromText( $parent );
+ $nt = self::newFromText( $parent );
if ( $nt ) {
$stack[$parent] = $nt->getParentCategoryTree( $children + [ $parent => 1 ] );
}
}
/**
- * Get the revision ID of the previous revision
- *
+ * Get next/previous revision ID relative to another revision ID
* @param int $revId Revision ID. Get the revision that was before this one.
* @param int $flags Title::GAID_FOR_UPDATE
- * @return int|bool Old revision ID, or false if none exists
- */
- public function getPreviousRevisionID( $revId, $flags = 0 ) {
- /* This function and getNextRevisionID have bad performance when
- used on a page with many revisions on mysql. An explicit extended
- primary key may help in some cases, if the PRIMARY KEY is banned:
- T159319 */
+ * @param string $dir 'next' or 'prev'
+ * @return int|bool New revision ID, or false if none exists
+ */
+ private function getRelativeRevisionID( $revId, $flags, $dir ) {
+ $revId = (int)$revId;
+ if ( $dir === 'next' ) {
+ $op = '>';
+ $sort = 'ASC';
+ } elseif ( $dir === 'prev' ) {
+ $op = '<';
+ $sort = 'DESC';
+ } else {
+ throw new InvalidArgumentException( '$dir must be "next" or "prev"' );
+ }
+
if ( $flags & self::GAID_FOR_UPDATE ) {
$db = wfGetDB( DB_MASTER );
} else {
$db = wfGetDB( DB_REPLICA, 'contributions' );
}
+
+ // Intentionally not caring if the specified revision belongs to this
+ // page. We only care about the timestamp.
+ $ts = $db->selectField( 'revision', 'rev_timestamp', [ 'rev_id' => $revId ], __METHOD__ );
+ if ( $ts === false ) {
+ $ts = $db->selectField( 'archive', 'ar_timestamp', [ 'ar_rev_id' => $revId ], __METHOD__ );
+ if ( $ts === false ) {
+ // Or should this throw an InvalidArgumentException or something?
+ return false;
+ }
+ }
+ $ts = $db->addQuotes( $ts );
+
$revId = $db->selectField( 'revision', 'rev_id',
[
'rev_page' => $this->getArticleID( $flags ),
- 'rev_id < ' . intval( $revId )
+ "rev_timestamp $op $ts OR (rev_timestamp = $ts AND rev_id $op $revId)"
],
__METHOD__,
- [ 'ORDER BY' => 'rev_id DESC', 'IGNORE INDEX' => 'PRIMARY' ]
+ [
+ 'ORDER BY' => "rev_timestamp $sort, rev_id $sort",
+ 'IGNORE INDEX' => 'rev_timestamp', // Probably needed for T159319
+ ]
);
if ( $revId === false ) {
}
}
+ /**
+ * Get the revision ID of the previous revision
+ *
+ * @param int $revId Revision ID. Get the revision that was before this one.
+ * @param int $flags Title::GAID_FOR_UPDATE
+ * @return int|bool Old revision ID, or false if none exists
+ */
+ public function getPreviousRevisionID( $revId, $flags = 0 ) {
+ return $this->getRelativeRevisionID( $revId, $flags, 'prev' );
+ }
+
/**
* Get the revision ID of the next revision
*
* @return int|bool Next revision ID, or false if none exists
*/
public function getNextRevisionID( $revId, $flags = 0 ) {
- if ( $flags & self::GAID_FOR_UPDATE ) {
- $db = wfGetDB( DB_MASTER );
- } else {
- $db = wfGetDB( DB_REPLICA, 'contributions' );
- }
- $revId = $db->selectField( 'revision', 'rev_id',
- [
- 'rev_page' => $this->getArticleID( $flags ),
- 'rev_id > ' . intval( $revId )
- ],
- __METHOD__,
- [ 'ORDER BY' => 'rev_id', 'IGNORE INDEX' => 'PRIMARY' ]
- );
-
- if ( $revId === false ) {
- return false;
- } else {
- return intval( $revId );
- }
+ return $this->getRelativeRevisionID( $revId, $flags, 'next' );
}
/**
[ 'rev_page' => $pageId ],
__METHOD__,
[
- 'ORDER BY' => 'rev_timestamp ASC',
- 'IGNORE INDEX' => 'rev_timestamp'
+ 'ORDER BY' => 'rev_timestamp ASC, rev_id ASC',
+ 'IGNORE INDEX' => 'rev_timestamp', // See T159319
]
);
if ( $row ) {