X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2FTitle.php;h=28bec0bdcec6290fda27f6c0e427739fcdf6cba7;hp=f69f1a4503b674f1b9ba1b55cd971fe93c07b7f1;hb=c05b8b7c473a7dd9c832f91366c45cb8a35c2df2;hpb=c9eb118548b5dc5e8dcf9dd7fed2b69f717df714 diff --git a/includes/Title.php b/includes/Title.php index f69f1a4503..28bec0bdce 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -23,6 +23,7 @@ */ use MediaWiki\Permissions\PermissionManager; +use Wikimedia\Assert\Assert; use Wikimedia\Rdbms\Database; use Wikimedia\Rdbms\IDatabase; use MediaWiki\Linker\LinkTarget; @@ -851,7 +852,10 @@ class Title implements LinkTarget, IDBAccessObject { /** * 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. @@ -870,10 +874,23 @@ class Title implements LinkTarget, IDBAccessObject { 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; } /** @@ -1128,14 +1145,16 @@ class Title implements LinkTarget, IDBAccessObject { /** * 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 ); } /** @@ -1150,11 +1169,15 @@ class Title implements LinkTarget, IDBAccessObject { /** * 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 ); } /** @@ -1515,8 +1538,11 @@ class Title implements LinkTarget, IDBAccessObject { /** * 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( @@ -1728,6 +1754,9 @@ class Title implements LinkTarget, IDBAccessObject { /** * 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(); @@ -1761,12 +1790,20 @@ class Title implements LinkTarget, IDBAccessObject { * @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(); @@ -1794,7 +1831,7 @@ class Title implements LinkTarget, IDBAccessObject { } /** - * 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 @@ -1806,7 +1843,12 @@ class Title implements LinkTarget, IDBAccessObject { * @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; } /** @@ -1845,7 +1887,12 @@ class Title implements LinkTarget, IDBAccessObject { * @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 + ); } /** @@ -2252,34 +2299,6 @@ class Title implements LinkTarget, IDBAccessObject { ->getPermissionErrors( $action, $user, $this, $rigor, $ignoreErrors ); } - /** - * Add the resulting error code to the errors array - * - * @param array $errors List of current errors - * @param array|string|MessageSpecifier|false $result Result of errors - * - * @return array List of errors - */ - private function resultToError( $errors, $result ) { - if ( is_array( $result ) && count( $result ) && !is_array( $result[0] ) ) { - // A single array representing an error - $errors[] = $result; - } elseif ( is_array( $result ) && is_array( $result[0] ) ) { - // A nested array representing multiple errors - $errors = array_merge( $errors, $result ); - } elseif ( $result !== '' && is_string( $result ) ) { - // A string representing a message-id - $errors[] = [ $result ]; - } elseif ( $result instanceof MessageSpecifier ) { - // A message specifier representing an error - $errors[] = [ $result ]; - } elseif ( $result === false ) { - // a generic "We don't want them to do that" - $errors[] = [ 'badaccess-group0' ]; - } - return $errors; - } - /** * Get a filtered list of all restriction types supported by this wiki. * @param bool $exists True to get all restriction types that apply to @@ -2907,7 +2926,7 @@ class Title implements LinkTarget, IDBAccessObject { $this->mHasSubpages = false; $subpages = $this->getSubpages( 1 ); if ( $subpages instanceof TitleArray ) { - $this->mHasSubpages = (bool)$subpages->count(); + $this->mHasSubpages = (bool)$subpages->current(); } } @@ -4248,7 +4267,7 @@ class Title implements LinkTarget, IDBAccessObject { * Get the timestamp when this page was updated since the user last saw it. * * @param User|null $user - * @return string|null + * @return string|bool|null String timestamp, false if not watched, null if nothing is unseen */ public function getNotificationTimestamp( $user = null ) { global $wgUser;