* Flag for use with factory methods like newFromLinkTarget() that have
* a $forceClone parameter. If set, the method must return a new instance.
* Without this flag, some factory methods may return existing instances.
+ *
+ * @since 1.33
*/
const NEW_CLONE = 'clone';
* unless $forceClone is "clone". If $forceClone is "clone" and the given TitleValue
* is already a Title instance, that instance is copied using the clone operator.
*
+ * @deprecated since 1.34, use newFromLinkTarget or castFromLinkTarget
+ *
* @param TitleValue $titleValue Assumed to be safe.
* @param string $forceClone set to NEW_CLONE to ensure a fresh instance is returned.
*
);
}
+ /**
+ * Same as newFromLinkTarget, but if passed null, returns null.
+ *
+ * @param LinkTarget|null $linkTarget Assumed to be safe (if not null).
+ *
+ * @return Title|null
+ */
+ public static function castFromLinkTarget( $linkTarget ) {
+ return $linkTarget ? self::newFromLinkTarget( $linkTarget ) : null;
+ }
+
/**
* Create a new Title from text, such as what one would find in a link. De-
* codes any HTML entities in the text.
/**
* Create a new Title for the Main Page
*
+ * This uses the 'mainpage' interface message, which could be specified in
+ * `$wgForceUIMsgAsContentMsg`. If that is the case, then calling this method
+ * will use the user language, which would involve initialising the session
+ * via `RequestContext::getMain()->getLanguage()`. For session-less endpoints,
+ * be sure to pass in a MessageLocalizer (such as your own RequestContext,
+ * or ResourceloaderContext) to prevent an error.
+ *
* @note The Title instance returned by this method is not guaranteed to be a fresh instance.
* It may instead be a cached instance created previously, with references to it remaining
* elsewhere.
*
- * @return Title The new object
+ * @param MessageLocalizer|null $localizer An optional context to use (since 1.34)
+ * @return Title
*/
- public static function newMainPage() {
- $title = self::newFromText( wfMessage( 'mainpage' )->inContentLanguage()->text() );
- // Don't give fatal errors if the message is broken
+ public static function newMainPage( MessageLocalizer $localizer = null ) {
+ if ( $localizer ) {
+ $msg = $localizer->msg( 'mainpage' );
+ } else {
+ $msg = wfMessage( 'mainpage' );
+ }
+
+ $title = self::newFromText( $msg->inContentLanguage()->text() );
+
+ // Every page renders at least one link to the Main Page (e.g. sidebar).
+ // If the localised value is invalid, don't produce fatal errors that
+ // would make the wiki inaccessible (and hard to fix the invalid message).
+ // Gracefully fallback...
if ( !$title ) {
$title = self::newFromText( 'Main Page' );
}
// Allow unicode if a single high-bit character appears
$r0 = sprintf( '\x%02x', $ord0 );
$allowUnicode = true;
+ // @phan-suppress-next-line PhanParamSuspiciousOrder false positive
} elseif ( strpos( '-\\[]^', $d0 ) !== false ) {
$r0 = '\\' . $d0;
} else {
/**
* Get a Title object associated with the talk page of this article
*
+ * @deprecated since 1.34, use NamespaceInfo::getTalkPage
* @return Title The object for the talk page
*/
public function getTalkPage() {
- return self::makeTitle( MWNamespace::getTalk( $this->mNamespace ), $this->mDbkeyform );
+ return self::castFromLinkTarget(
+ MediaWikiServices::getInstance()->getNamespaceInfo()->getTalkPage( $this ) );
}
/**
* Get a title object associated with the subject page of this
* talk page
*
+ * @deprecated since 1.34, use NamespaceInfo::getSubjectPage
* @return Title The object for the subject page
*/
public function getSubjectPage() {
- // Is this the same title?
- $subjectNS = MWNamespace::getSubject( $this->mNamespace );
- if ( $this->mNamespace == $subjectNS ) {
- return $this;
- }
- return self::makeTitle( $subjectNS, $this->mDbkeyform );
+ return self::castFromLinkTarget(
+ MediaWikiServices::getInstance()->getNamespaceInfo()->getSubjectPage( $this ) );
}
/**
* Get the other title for this page, if this is a subject page
* get the talk page, if it is a subject page get the talk page
*
+ * @deprecated since 1.34, use NamespaceInfo::getAssociatedPage
* @since 1.25
* @throws MWException If the page doesn't have an other page
* @return Title
*/
public function getOtherPage() {
- if ( $this->isSpecialPage() ) {
- throw new MWException( 'Special pages cannot have other pages' );
- }
- if ( $this->isTalkPage() ) {
- return $this->getSubjectPage();
- } else {
- if ( !$this->canHaveTalkPage() ) {
- throw new MWException( "{$this->getPrefixedText()} does not have an other page" );
- }
- return $this->getTalkPage();
- }
+ return self::castFromLinkTarget(
+ MediaWikiServices::getInstance()->getNamespaceInfo()->getAssociatedPage( $this ) );
}
/**
* protocol-relative, the URL will be expanded to http://
*
* @see self::getLocalURL for the arguments.
- * @param string $query
- * @param string|bool $query2
+ * @param string|string[] $query
+ * @param string|bool $query2 Deprecated
* @return string The URL
*/
public function getInternalURL( $query = '', $query2 = false ) {
* NOTE: Unlike getInternalURL(), the canonical URL includes the fragment
*
* @see self::getLocalURL for the arguments.
- * @param string $query
- * @param string|bool $query2
+ * @param string|string[] $query
+ * @param string|bool $query2 Deprecated
* @return string The URL
* @since 1.18
*/
$id = $this->getArticleID();
if ( $id ) {
$fname = __METHOD__;
- $loadRestrictionsFromDb = function ( Database $dbr ) use ( $fname, $id ) {
+ $loadRestrictionsFromDb = function ( IDatabase $dbr ) use ( $fname, $id ) {
return iterator_to_array(
$dbr->select(
'page_restrictions',
array $changeTags = []
) {
global $wgUser;
- $err = $this->isValidMoveOperation( $nt, $auth, $reason );
- if ( is_array( $err ) ) {
- // Auto-block user's IP if the account was "hard" blocked
- $wgUser->spreadAnyEditBlock();
- return $err;
- }
- // Check suppressredirect permission
- if ( $auth && !$wgUser->isAllowed( 'suppressredirect' ) ) {
- $createRedirect = true;
- }
$mp = new MovePage( $this, $nt );
- $status = $mp->move( $wgUser, $reason, $createRedirect, $changeTags );
+ $method = $auth ? 'moveIfAllowed' : 'move';
+ $status = $mp->$method( $wgUser, $reason, $createRedirect, $changeTags );
if ( $status->isOK() ) {
return true;
} else {
* @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;
- }
+ $rl = MediaWikiServices::getInstance()->getRevisionLookup();
+ $rlFlags = $flags === self::GAID_FOR_UPDATE ? IDBAccessObject::READ_LATEST : 0;
+ $rev = $rl->getRevisionById( $revId, $rlFlags );
+ if ( !$rev ) {
+ return false;
}
- $ts = $db->addQuotes( $ts );
-
- $revId = $db->selectField( 'revision', 'rev_id',
- [
- 'rev_page' => $this->getArticleID( $flags ),
- "rev_timestamp $op $ts OR (rev_timestamp = $ts AND rev_id $op $revId)"
- ],
- __METHOD__,
- [
- 'ORDER BY' => "rev_timestamp $sort, rev_id $sort",
- 'IGNORE INDEX' => 'rev_timestamp', // Probably needed for T159319
- ]
- );
-
- if ( $revId === false ) {
+ $oldRev = $dir === 'next'
+ ? $rl->getNextRevision( $rev, $rlFlags )
+ : $rl->getPreviousRevision( $rev, $rlFlags );
+ if ( !$oldRev ) {
return false;
- } else {
- return intval( $revId );
}
+ return $oldRev->getId();
}
/**
* Get the revision ID of the previous revision
*
+ * @deprecated since 1.34, use RevisionLookup::getPreviousRevision
* @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
/**
* Get the revision ID of the next revision
*
+ * @deprecated since 1.34, use RevisionLookup::getNextRevision
* @param int $revId Revision ID. Get the revision that was after this one.
* @param int $flags Title::GAID_FOR_UPDATE
* @return int|bool Next revision ID, or false if none exists
/**
* Compare with another title.
*
- * @param Title $title
+ * @param LinkTarget $title
* @return bool
*/
- public function equals( Title $title ) {
+ public function equals( LinkTarget $title ) {
// Note: === is necessary for proper matching of number-like titles.
- return $this->mInterwiki === $title->mInterwiki
- && $this->mNamespace == $title->mNamespace
- && $this->mDbkeyform === $title->mDbkeyform;
+ return $this->mInterwiki === $title->getInterwiki()
+ && $this->mNamespace == $title->getNamespace()
+ && $this->mDbkeyform === $title->getDBkey();
}
/**