*/
use MediaWiki\Permissions\PermissionManager;
+use Wikimedia\Assert\Assert;
use Wikimedia\Rdbms\Database;
use Wikimedia\Rdbms\IDatabase;
use MediaWiki\Linker\LinkTarget;
/**
* Returns true if the title is valid, false if it is invalid.
*
- * Valid titles can be round-tripped via makeTitleSafe() and newFromText().
+ * Valid titles can be round-tripped via makeTitle() and newFromText().
+ * Their DB key can be used in the database, though it may not have the correct
+ * capitalization.
+ *
* Invalid titles may get returned from makeTitle(), and it may be useful to
* allow them to exist, e.g. in order to process log entries about pages in
* namespaces that belong to extensions that are no longer installed.
try {
$services->getTitleParser()->parseTitle( $this->mDbkeyform, $this->mNamespace );
- return true;
} catch ( MalformedTitleException $ex ) {
return false;
}
+
+ try {
+ // Title value applies basic syntax checks. Should perhaps be moved elsewhere.
+ new TitleValue(
+ $this->mNamespace,
+ $this->mDbkeyform,
+ $this->mFragment,
+ $this->mInterwiki
+ );
+ } catch ( InvalidArgumentException $ex ) {
+ return false;
+ }
+
+ return true;
}
/**
/**
* Can this title have a corresponding talk page?
*
- * @see NamespaceInfo::hasTalkNamespace
+ * False for relative section links (with getText() === ''),
+ * interwiki links (with getInterwiki() !== ''), and pages in NS_SPECIAL.
+ *
+ * @see NamespaceInfo::canHaveTalkPage
* @since 1.30
*
* @return bool True if this title either is a talk page or can have a talk page associated.
*/
public function canHaveTalkPage() {
- return MediaWikiServices::getInstance()->getNamespaceInfo()->
- hasTalkNamespace( $this->mNamespace );
+ return MediaWikiServices::getInstance()->getNamespaceInfo()->canHaveTalkPage( $this );
}
/**
/**
* Can this title be added to a user's watchlist?
*
+ * False for relative section links (with getText() === ''),
+ * interwiki links (with getInterwiki() !== ''), and pages in NS_SPECIAL.
+ *
* @return bool
*/
public function isWatchable() {
- return !$this->isExternal() && MediaWikiServices::getInstance()->getNamespaceInfo()->
- isWatchable( $this->mNamespace );
+ $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
+ return $this->getText() !== '' && !$this->isExternal() &&
+ $nsInfo->isWatchable( $this->mNamespace );
}
/**
/**
* Get a Title object associated with the talk page of this article
*
- * @deprecated since 1.34, use NamespaceInfo::getTalkPage
+ * @deprecated since 1.34, use getTalkPageIfDefined() or NamespaceInfo::getTalkPage()
+ * with NamespaceInfo::canHaveTalkPage().
* @return Title The object for the talk page
+ * @throws MWException if $target doesn't have talk pages, e.g. because it's in NS_SPECIAL
+ * or because it's a relative link, or an interwiki link.
*/
public function getTalkPage() {
return self::castFromLinkTarget(
/**
* Get the root page name text without a namespace, i.e. the leftmost part before any slashes
*
+ * @note the return value may contain trailing whitespace and is thus
+ * not safe for use with makeTitle or TitleValue.
+ *
* @par Example:
* @code
* Title::newFromText('User:Foo/Bar/Baz')->getRootText();
* @since 1.20
*/
public function getRootTitle() {
- return self::makeTitle( $this->mNamespace, $this->getRootText() );
+ $title = self::makeTitleSafe( $this->mNamespace, $this->getRootText() );
+ Assert::postcondition(
+ $title !== null,
+ 'makeTitleSafe() should always return a Title for the text returned by getRootText().'
+ );
+ return $title;
}
/**
* Get the base page name without a namespace, i.e. the part before the subpage name
*
+ * @note the return value may contain trailing whitespace and is thus
+ * not safe for use with makeTitle or TitleValue.
+ *
* @par Example:
* @code
* Title::newFromText('User:Foo/Bar/Baz')->getBaseText();
}
/**
- * Get the base page name title, i.e. the part before the subpage name
+ * Get the base page name title, i.e. the part before the subpage name.
*
* @par Example:
* @code
* @since 1.20
*/
public function getBaseTitle() {
- return self::makeTitle( $this->mNamespace, $this->getBaseText() );
+ $title = self::makeTitleSafe( $this->mNamespace, $this->getBaseText() );
+ Assert::postcondition(
+ $title !== null,
+ 'makeTitleSafe() should always return a Title for the text returned by getBaseText().'
+ );
+ return $title;
}
/**
* @since 1.20
*/
public function getSubpage( $text ) {
- return self::makeTitleSafe( $this->mNamespace, $this->getText() . '/' . $text );
+ return self::makeTitleSafe(
+ $this->mNamespace,
+ $this->getText() . '/' . $text,
+ '',
+ $this->mInterwiki
+ );
}
/**