X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FTitle.php;h=34966686b9cbc16d3f3125e5ccef1b6944f1344f;hb=b2017a11a8bfe09fc6d9ad975022f87aae450ccf;hp=8b4075b4de6816a6748fe826f11c181e7b0d1ede;hpb=41fa0b12e7c4d38c7e7d20ac099394015ef7a55c;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Title.php b/includes/Title.php index 8b4075b4de..34966686b9 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -36,7 +36,7 @@ use MediaWiki\MediaWikiServices; * @note Consider using a TitleValue object instead. TitleValue is more lightweight * and does not rely on global state or the database. */ -class Title implements LinkTarget { +class Title implements LinkTarget, IDBAccessObject { /** @var MapCacheLRU */ static private $titleCache = null; @@ -954,6 +954,7 @@ class Title implements LinkTarget { /** * Get the DB key with the initial letter case as specified by the user + * @deprecated since 1.33; please use Title::getDBKey() instead * * @return string DB key */ @@ -1661,7 +1662,7 @@ class Title implements LinkTarget { $p = $this->mInterwiki . ':'; } - if ( 0 != $this->mNamespace ) { + if ( $this->mNamespace != 0 ) { $nsText = $this->getNsText(); if ( $nsText === false ) { @@ -2690,14 +2691,34 @@ class Title implements LinkTarget { } $useReplica = ( $rigor !== 'secure' ); - if ( ( $action == 'edit' || $action == 'create' ) - && !$user->isBlockedFrom( $this, $useReplica ) - ) { - // Don't block the user from editing their own talk page unless they've been - // explicitly blocked from that too. - } elseif ( $user->isBlocked() && $user->getBlock()->prevents( $action ) !== false ) { + $block = $user->getBlock( $useReplica ); + + // The block may explicitly allow an action (like "read" or "upload"). + if ( $block && $block->prevents( $action ) === false ) { + return $errors; + } + + // Determine if the user is blocked from this action on this page. + // What gets passed into this method is a user right, not an action nmae. + // There is no way to instantiate an action by restriction. However, this + // will get the action where the restriction is the same. This may result + // in actions being blocked that shouldn't be. + if ( Action::exists( $action ) ) { // @todo FIXME: Pass the relevant context into this function. - $errors[] = $user->getBlock()->getPermissionsError( RequestContext::getMain() ); + $action = Action::factory( $action, WikiPage::factory( $this ), RequestContext::getMain() ); + } else { + $action = null; + } + + // If no action object is returned, assume that the action requires unblock + // which is the default. + if ( !$action || $action->requiresUnblock() ) { + if ( $user->isBlockedFrom( $this, $useReplica ) ) { + // @todo FIXME: Pass the relevant context into this function. + $errors[] = $block + ? $block->getPermissionsError( RequestContext::getMain() ) + : [ 'actionblockedtext' ]; + } } return $errors; @@ -2860,10 +2881,12 @@ class Title implements LinkTarget { } $errors = []; - while ( count( $checks ) > 0 && - !( $short && count( $errors ) > 0 ) ) { - $method = array_shift( $checks ); + foreach ( $checks as $method ) { $errors = $this->$method( $action, $user, $errors, $rigor, $short ); + + if ( $short && $errors !== [] ) { + break; + } } return $errors; @@ -3277,6 +3300,9 @@ class Title implements LinkTarget { * Example: "edit=autoconfirmed,sysop:move=sysop" */ public function loadRestrictionsFromRows( $rows, $oldFashionedRestrictions = null ) { + // This function will only read rows from a table that we migrated away + // from before adding READ_LATEST support to loadRestrictions, so we + // don't need to support reading from DB_MASTER here. $dbr = wfGetDB( DB_REPLICA ); $restrictionTypes = $this->getRestrictionTypes(); @@ -3347,35 +3373,50 @@ class Title implements LinkTarget { * indicating who can move or edit the page from the page table, (pre 1.10) rows. * Edit and move sections are separated by a colon * Example: "edit=autoconfirmed,sysop:move=sysop" + * @param int $flags A bit field. If self::READ_LATEST is set, skip replicas and read + * from the master DB. */ - public function loadRestrictions( $oldFashionedRestrictions = null ) { - if ( $this->mRestrictionsLoaded ) { + public function loadRestrictions( $oldFashionedRestrictions = null, $flags = 0 ) { + $readLatest = DBAccessObjectUtils::hasFlags( $flags, self::READ_LATEST ); + if ( $this->mRestrictionsLoaded && !$readLatest ) { return; } + // TODO: should probably pass $flags into getArticleID, but it seems hacky + // to mix READ_LATEST and GAID_FOR_UPDATE, even if they have the same value. + // Maybe deprecate GAID_FOR_UPDATE now that we implement IDBAccessObject? $id = $this->getArticleID(); if ( $id ) { - $cache = ObjectCache::getMainWANInstance(); $fname = __METHOD__; - $rows = $cache->getWithSetCallback( - // Page protections always leave a new null revision - $cache->makeKey( 'page-restrictions', $id, $this->getLatestRevID() ), - $cache::TTL_DAY, - function ( $curValue, &$ttl, array &$setOpts ) use ( $fname ) { - $dbr = wfGetDB( DB_REPLICA ); - - $setOpts += Database::getCacheSetOptions( $dbr ); - - return iterator_to_array( - $dbr->select( - 'page_restrictions', - [ 'pr_type', 'pr_expiry', 'pr_level', 'pr_cascade' ], - [ 'pr_page' => $this->getArticleID() ], - $fname - ) - ); - } - ); + $loadRestrictionsFromDb = function ( Database $dbr ) use ( $fname, $id ) { + return iterator_to_array( + $dbr->select( + 'page_restrictions', + [ 'pr_type', 'pr_expiry', 'pr_level', 'pr_cascade' ], + [ 'pr_page' => $id ], + $fname + ) + ); + }; + + if ( $readLatest ) { + $dbr = wfGetDB( DB_MASTER ); + $rows = $loadRestrictionsFromDb( $dbr ); + } else { + $cache = ObjectCache::getMainWANInstance(); + $rows = $cache->getWithSetCallback( + // Page protections always leave a new null revision + $cache->makeKey( 'page-restrictions', $id, $this->getLatestRevID() ), + $cache::TTL_DAY, + function ( $curValue, &$ttl, array &$setOpts ) use ( $loadRestrictionsFromDb ) { + $dbr = wfGetDB( DB_REPLICA ); + + $setOpts += Database::getCacheSetOptions( $dbr ); + + return $loadRestrictionsFromDb( $dbr ); + } + ); + } $this->loadRestrictionsFromRows( $rows, $oldFashionedRestrictions ); } else { @@ -3573,7 +3614,7 @@ class Title implements LinkTarget { $this->mArticleID = $linkCache->addLinkObj( $this ); $linkCache->forUpdate( $oldUpdate ); } else { - if ( -1 == $this->mArticleID ) { + if ( $this->mArticleID == -1 ) { $this->mArticleID = $linkCache->addLinkObj( $this ); } } @@ -5220,10 +5261,9 @@ class Title implements LinkTarget { if ( MWNamespace::hasSubpages( $this->mNamespace ) ) { // Optional notice for page itself and any parent page - $parts = explode( '/', $this->mDbkeyform ); $editnotice_base = $editnotice_ns; - while ( count( $parts ) > 0 ) { - $editnotice_base .= '-' . array_shift( $parts ); + foreach ( explode( '/', $this->mDbkeyform ) as $part ) { + $editnotice_base .= '-' . $part; $msg = wfMessage( $editnotice_base ); if ( $msg->exists() ) { $html = $msg->parseAsBlock();