MediaWiki  master
RestrictionStore.php
Go to the documentation of this file.
1 <?php
2 
3 namespace MediaWiki\Permissions;
4 
5 use CommentStore;
8 use LinkCache;
16 use stdClass;
17 use Title;
18 use WANObjectCache;
22 
29 
31  public const CONSTRUCTOR_OPTIONS = [
32  'NamespaceProtection',
33  'RestrictionLevels',
34  'RestrictionTypes',
35  'SemiprotectedRestrictionLevels',
36  ];
37 
39  private $options;
40 
42  private $wanCache;
43 
45  private $loadBalancer;
46 
48  private $linkCache;
49 
51  private $commentStore;
52 
54  private $hookContainer;
55 
57  private $hookRunner;
58 
60  private $pageStore;
61 
74  private $cache = [];
75 
85  public function __construct(
93  ) {
94  $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
95  $this->options = $options;
96  $this->wanCache = $wanCache;
97  $this->loadBalancer = $loadBalancer;
98  $this->linkCache = $linkCache;
99  $this->commentStore = $commentStore;
100  $this->hookContainer = $hookContainer;
101  $this->hookRunner = new HookRunner( $hookContainer );
102  $this->pageStore = $pageStore;
103  }
104 
116  public function getRestrictions( PageIdentity $page, string $action ): array {
117  $page->assertWiki( PageIdentity::LOCAL );
118 
119  $restrictions = $this->getAllRestrictions( $page );
120  return $restrictions[$action] ?? [];
121  }
122 
130  public function getAllRestrictions( PageIdentity $page ): array {
131  $page->assertWiki( PageIdentity::LOCAL );
132 
133  if ( !$this->areRestrictionsLoaded( $page ) ) {
134  $this->loadRestrictions( $page );
135  }
136  return $this->cache[CacheKeyHelper::getKeyForPage( $page )]['restrictions'] ?? [];
137  }
138 
148  public function getRestrictionExpiry( PageIdentity $page, string $action ): ?string {
149  $page->assertWiki( PageIdentity::LOCAL );
150 
151  if ( !$this->areRestrictionsLoaded( $page ) ) {
152  $this->loadRestrictions( $page );
153  }
154  return $this->cache[CacheKeyHelper::getKeyForPage( $page )]['expiry'][$action] ?? null;
155  }
156 
171  public function getCreateProtection( PageIdentity $page ): ?array {
172  $page->assertWiki( PageIdentity::LOCAL );
173 
174  $protection = $this->getCreateProtectionInternal( $page );
175  // TODO: the remapping below probably need to be migrated into other method one day
176  if ( $protection ) {
177  if ( $protection['permission'] == 'sysop' ) {
178  $protection['permission'] = 'editprotected'; // B/C
179  }
180  if ( $protection['permission'] == 'autoconfirmed' ) {
181  $protection['permission'] = 'editsemiprotected'; // B/C
182  }
183  }
184  return $protection;
185  }
186 
193  public function deleteCreateProtection( PageIdentity $page ): void {
194  $page->assertWiki( PageIdentity::LOCAL );
195 
196  $dbw = $this->loadBalancer->getConnectionRef( DB_PRIMARY );
197  $dbw->delete(
198  'protected_titles',
199  [ 'pt_namespace' => $page->getNamespace(), 'pt_title' => $page->getDBkey() ],
200  __METHOD__
201  );
202  $this->cache[CacheKeyHelper::getKeyForPage( $page )]['create_protection'] = null;
203  }
204 
213  public function isSemiProtected( PageIdentity $page, string $action = 'edit' ): bool {
214  $page->assertWiki( PageIdentity::LOCAL );
215 
216  $restrictions = $this->getRestrictions( $page, $action );
217  $semi = $this->options->get( 'SemiprotectedRestrictionLevels' );
218  if ( !$restrictions || !$semi ) {
219  // Not protected, or all protection is full protection
220  return false;
221  }
222 
223  // Remap autoconfirmed to editsemiprotected for BC
224  foreach ( array_keys( $semi, 'editsemiprotected' ) as $key ) {
225  $semi[$key] = 'autoconfirmed';
226  }
227  foreach ( array_keys( $restrictions, 'editsemiprotected' ) as $key ) {
228  $restrictions[$key] = 'autoconfirmed';
229  }
230 
231  return !array_diff( $restrictions, $semi );
232  }
233 
241  public function isProtected( PageIdentity $page, string $action = '' ): bool {
242  $page->assertWiki( PageIdentity::LOCAL );
243 
244  // Special pages have inherent protection (TODO: remove after switch to ProperPageIdentity)
245  if ( $page->getNamespace() === NS_SPECIAL ) {
246  return true;
247  }
248 
249  // Check regular protection levels
250  $applicableTypes = $this->listApplicableRestrictionTypes( $page );
251 
252  if ( $action === '' ) {
253  foreach ( $applicableTypes as $type ) {
254  if ( $this->isProtected( $page, $type ) ) {
255  return true;
256  }
257  }
258  return false;
259  }
260 
261  if ( !in_array( $action, $applicableTypes ) ) {
262  return false;
263  }
264 
265  return (bool)array_diff(
266  array_intersect(
267  $this->getRestrictions( $page, $action ),
268  $this->options->get( 'RestrictionLevels' )
269  ),
270  [ '' ]
271  );
272  }
273 
280  public function isCascadeProtected( PageIdentity $page ): bool {
281  $page->assertWiki( PageIdentity::LOCAL );
282 
283  return $this->getCascadeProtectionSourcesInternal( $page, true );
284  }
285 
292  public function listApplicableRestrictionTypes( PageIdentity $page ): array {
293  $page->assertWiki( PageIdentity::LOCAL );
294 
295  if ( !$page->canExist() ) {
296  return [];
297  }
298 
299  $types = $this->listAllRestrictionTypes( $page->exists() );
300 
301  if ( $page->getNamespace() !== NS_FILE ) {
302  // Remove the upload restriction for non-file titles
303  $types = array_values( array_diff( $types, [ 'upload' ] ) );
304  }
305 
306  if ( $this->hookContainer->isRegistered( 'TitleGetRestrictionTypes' ) ) {
307  $this->hookRunner->onTitleGetRestrictionTypes(
308  Title::castFromPageIdentity( $page ), $types );
309  }
310 
311  return $types;
312  }
313 
321  public function listAllRestrictionTypes( bool $exists = true ): array {
322  $types = $this->options->get( 'RestrictionTypes' );
323  if ( $exists ) {
324  // Remove the create restriction for existing titles
325  return array_values( array_diff( $types, [ 'create' ] ) );
326  }
327 
328  // Only the create and upload restrictions apply to non-existing titles
329  return array_values( array_intersect( $types, [ 'create', 'upload' ] ) );
330  }
331 
343  public function loadRestrictions(
344  PageIdentity $page, int $flags = IDBAccessObject::READ_NORMAL, ?string $oldRestrictions = null
345  ): void {
346  $page->assertWiki( PageIdentity::LOCAL );
347 
348  if ( !$page->canExist() ) {
349  return;
350  }
351 
352  $readLatest = DBAccessObjectUtils::hasFlags( $flags, IDBAccessObject::READ_LATEST );
353 
354  if ( $this->areRestrictionsLoaded( $page ) && !$readLatest ) {
355  return;
356  }
357 
358  $cacheEntry = &$this->cache[CacheKeyHelper::getKeyForPage( $page )];
359 
360  $cacheEntry['restrictions'] = [];
361 
362  // XXX Work around https://phabricator.wikimedia.org/T287575
363  if ( $readLatest ) {
364  $page = $this->pageStore->getPageByReference( $page, $flags ) ?? $page;
365  }
366  $id = $page->getId();
367  if ( $id ) {
368  $fname = __METHOD__;
369  $loadRestrictionsFromDb = static function ( IDatabase $dbr ) use ( $fname, $id ) {
370  return iterator_to_array(
371  $dbr->select(
372  'page_restrictions',
373  [ 'pr_type', 'pr_expiry', 'pr_level', 'pr_cascade' ],
374  [ 'pr_page' => $id ],
375  $fname
376  )
377  );
378  };
379 
380  if ( $readLatest ) {
381  $dbr = $this->loadBalancer->getConnectionRef( DB_PRIMARY );
382  $rows = $loadRestrictionsFromDb( $dbr );
383  } else {
384  $this->linkCache->addLinkObj( $page );
385  $latestRev = $this->linkCache->getGoodLinkFieldObj( $page, 'revision' );
386  $rows = $this->wanCache->getWithSetCallback(
387  // Page protections always leave a new null revision
388  $this->wanCache->makeKey( 'page-restrictions', 'v1', $id, $latestRev ),
389  $this->wanCache::TTL_DAY,
390  function ( $curValue, &$ttl, array &$setOpts ) use ( $loadRestrictionsFromDb ) {
391  $dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA );
392  $setOpts += Database::getCacheSetOptions( $dbr );
393  if ( $this->loadBalancer->hasOrMadeRecentPrimaryChanges() ) {
394  // TODO: cleanup Title cache and caller assumption mess in general
395  $ttl = WANObjectCache::TTL_UNCACHEABLE;
396  }
397 
398  return $loadRestrictionsFromDb( $dbr );
399  }
400  );
401  }
402 
403  $this->loadRestrictionsFromRows( $page, $rows, $oldRestrictions );
404  } else {
405  $titleProtection = $this->getCreateProtectionInternal( $page );
406 
407  if ( $titleProtection ) {
408  $now = wfTimestampNow();
409  $expiry = $titleProtection['expiry'];
410 
411  if ( !$expiry || $expiry > $now ) {
412  // Apply the restrictions
413  $cacheEntry['expiry']['create'] = $expiry ?: null;
414  $cacheEntry['restrictions']['create'] =
415  explode( ',', trim( $titleProtection['permission'] ) );
416  } else {
417  // Get rid of the old restrictions
418  $cacheEntry['create_protection'] = null;
419  }
420  } else {
421  $cacheEntry['expiry']['create'] = 'infinity';
422  }
423  }
424  }
425 
436  public function loadRestrictionsFromRows(
437  PageIdentity $page, array $rows, ?string $oldRestrictions = null
438  ): void {
439  $page->assertWiki( PageIdentity::LOCAL );
440 
441  $cacheEntry = &$this->cache[CacheKeyHelper::getKeyForPage( $page )];
442 
443  $restrictionTypes = $this->listApplicableRestrictionTypes( $page );
444 
445  foreach ( $restrictionTypes as $type ) {
446  $cacheEntry['restrictions'][$type] = [];
447  $cacheEntry['expiry'][$type] = 'infinity';
448  }
449 
450  $cacheEntry['cascade'] = false;
451 
452  // Backwards-compatibility: also load the restrictions from the page record (old format).
453  // Don't include in test coverage, we're planning to drop support.
454  // @codeCoverageIgnoreStart
455  $cacheEntry['oldRestrictions'] = $oldRestrictions ?? $cacheEntry['oldRestrictions'] ?? null;
456 
457  if ( $cacheEntry['oldRestrictions'] === null ) {
458  $this->linkCache->addLinkObj( $page );
459  $cachedOldRestrictions = $this->linkCache->getGoodLinkFieldObj( $page, 'restrictions' );
460  if ( $cachedOldRestrictions !== null ) {
461  $cacheEntry['oldRestrictions'] = $cachedOldRestrictions;
462  }
463  }
464 
465  if ( $cacheEntry['oldRestrictions'] ) {
466  $cacheEntry['restrictions'] =
467  $this->convertOldRestrictions( $cacheEntry['oldRestrictions'] );
468  }
469  // @codeCoverageIgnoreEnd
470 
471  if ( !$rows ) {
472  return;
473  }
474 
475  // New restriction format -- load second to make them override old-style restrictions.
476  $now = wfTimestampNow();
477 
478  // Cycle through all the restrictions.
479  foreach ( $rows as $row ) {
480  // Don't take care of restrictions types that aren't allowed
481  if ( !in_array( $row->pr_type, $restrictionTypes ) ) {
482  continue;
483  }
484 
485  $dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA );
486  $expiry = $dbr->decodeExpiry( $row->pr_expiry );
487 
488  // Only apply the restrictions if they haven't expired!
489  // XXX Why would !$expiry ever be true? It should always be either 'infinity' or a
490  // string consisting of 14 digits. Likewise for the ?: below.
491  if ( !$expiry || $expiry > $now ) {
492  $cacheEntry['expiry'][$row->pr_type] = $expiry ?: null;
493  $cacheEntry['restrictions'][$row->pr_type]
494  = explode( ',', trim( $row->pr_level ) );
495  if ( $row->pr_cascade ) {
496  $cacheEntry['cascade'] = true;
497  }
498  }
499  }
500  }
501 
511  private function convertOldRestrictions( string $oldRestrictions ): array {
512  $ret = [];
513  foreach ( explode( ':', trim( $oldRestrictions ) ) as $restrict ) {
514  $restrictionPair = explode( '=', trim( $restrict ) );
515  if ( count( $restrictionPair ) == 1 ) {
516  // old old format should be treated as edit/move restriction
517  $ret['edit'] = explode( ',', trim( $restrictionPair[0] ) );
518  $ret['move'] = explode( ',', trim( $restrictionPair[0] ) );
519  } else {
520  $restriction = trim( $restrictionPair[1] );
521  if ( $restriction != '' ) { // some old entries are empty
522  $ret[$restrictionPair[0]] = explode( ',', $restriction );
523  }
524  }
525  }
526  return $ret;
527  }
528 
539  private function getCreateProtectionInternal( PageIdentity $page ): ?array {
540  // Can't protect pages in special namespaces
541  if ( !$page->canExist() ) {
542  return null;
543  }
544 
545  // Can't apply this type of protection to pages that exist.
546  if ( $page->exists() ) {
547  return null;
548  }
549 
550  $cacheEntry = &$this->cache[CacheKeyHelper::getKeyForPage( $page )];
551 
552  if ( !$cacheEntry || !array_key_exists( 'create_protection', $cacheEntry ) ) {
553  $dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA );
554  $commentQuery = $this->commentStore->getJoin( 'pt_reason' );
555  $row = $dbr->selectRow(
556  [ 'protected_titles' ] + $commentQuery['tables'],
557  [ 'pt_user', 'pt_expiry', 'pt_create_perm' ] + $commentQuery['fields'],
558  [ 'pt_namespace' => $page->getNamespace(), 'pt_title' => $page->getDBkey() ],
559  __METHOD__,
560  [],
561  $commentQuery['joins']
562  );
563 
564  if ( $row ) {
565  $cacheEntry['create_protection'] = [
566  'user' => $row->pt_user,
567  'expiry' => $dbr->decodeExpiry( $row->pt_expiry ),
568  'permission' => $row->pt_create_perm,
569  'reason' => $this->commentStore->getComment( 'pt_reason', $row )->text,
570  ];
571  } else {
572  $cacheEntry['create_protection'] = null;
573  }
574 
575  }
576 
577  return $cacheEntry['create_protection'];
578  }
579 
590  public function getCascadeProtectionSources( PageIdentity $page ): array {
591  $page->assertWiki( PageIdentity::LOCAL );
592 
593  return $this->getCascadeProtectionSourcesInternal( $page, false );
594  }
595 
605  PageIdentity $page, bool $shortCircuit = false
606  ) {
607  $cacheEntry = &$this->cache[CacheKeyHelper::getKeyForPage( $page )];
608 
609  if ( !$shortCircuit && isset( $cacheEntry['cascade_sources'] ) ) {
610  return $cacheEntry['cascade_sources'];
611  } elseif ( $shortCircuit && isset( $cacheEntry['has_cascading'] ) ) {
612  return $cacheEntry['has_cascading'];
613  }
614 
615  if ( $page->getNamespace() === NS_FILE ) {
616  // Files transclusion may receive cascading protection in the future
617  // see https://phabricator.wikimedia.org/T241453
618  $tables = [ 'imagelinks', 'page_restrictions' ];
619  $where_clauses = [
620  'il_to' => $page->getDBkey(),
621  'il_from=pr_page',
622  'pr_cascade' => 1
623  ];
624  } else {
625  $tables = [ 'templatelinks', 'page_restrictions' ];
626  $where_clauses = [
627  'tl_namespace' => $page->getNamespace(),
628  'tl_title' => $page->getDBkey(),
629  'tl_from=pr_page',
630  'pr_cascade' => 1
631  ];
632  }
633 
634  if ( $shortCircuit ) {
635  $cols = [ 'pr_expiry' ];
636  } else {
637  $cols = [ 'pr_page', 'page_namespace', 'page_title',
638  'pr_expiry', 'pr_type', 'pr_level' ];
639  $where_clauses[] = 'page_id=pr_page';
640  $tables[] = 'page';
641  }
642 
643  $dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA );
644  $res = $dbr->select( $tables, $cols, $where_clauses, __METHOD__ );
645 
646  $sources = [];
647  $pageRestrictions = [];
648  $now = wfTimestampNow();
649 
650  foreach ( $res as $row ) {
651  $expiry = $dbr->decodeExpiry( $row->pr_expiry );
652  if ( $expiry > $now ) {
653  if ( $shortCircuit ) {
654  $cacheEntry['has_cascading'] = true;
655  return true;
656  }
657 
658  $sources[$row->pr_page] = new PageIdentityValue( $row->pr_page,
659  $row->page_namespace, $row->page_title, PageIdentity::LOCAL );
660  // Add groups needed for each restriction type if its not already there
661  // Make sure this restriction type still exists
662 
663  if ( !isset( $pageRestrictions[$row->pr_type] ) ) {
664  $pageRestrictions[$row->pr_type] = [];
665  }
666 
667  if ( !in_array( $row->pr_level, $pageRestrictions[$row->pr_type] ) ) {
668  $pageRestrictions[$row->pr_type][] = $row->pr_level;
669  }
670  }
671  }
672 
673  $cacheEntry['has_cascading'] = (bool)$sources;
674 
675  if ( $shortCircuit ) {
676  return false;
677  }
678 
679  $cacheEntry['cascade_sources'] = [ $sources, $pageRestrictions ];
680  return [ $sources, $pageRestrictions ];
681  }
682 
688  public function areRestrictionsLoaded( PageIdentity $page ): bool {
689  $page->assertWiki( PageIdentity::LOCAL );
690 
691  return isset( $this->cache[CacheKeyHelper::getKeyForPage( $page )]['restrictions'] );
692  }
693 
700  public function areCascadeProtectionSourcesLoaded( PageIdentity $page ): bool {
701  $page->assertWiki( PageIdentity::LOCAL );
702 
703  return isset( $this->cache[CacheKeyHelper::getKeyForPage( $page )]['cascade_sources'] );
704  }
705 
712  public function areRestrictionsCascading( PageIdentity $page ): bool {
713  $page->assertWiki( PageIdentity::LOCAL );
714 
715  if ( !$this->areRestrictionsLoaded( $page ) ) {
716  $this->loadRestrictions( $page );
717  }
718  return $this->cache[CacheKeyHelper::getKeyForPage( $page )]['cascade'] ?? false;
719  }
720 
728  public function flushRestrictions( PageIdentity $page ): void {
729  $page->assertWiki( PageIdentity::LOCAL );
730 
731  unset( $this->cache[CacheKeyHelper::getKeyForPage( $page )] );
732  }
733 
744  public function registerOldRestrictions( PageIdentity $page, string $oldRestrictions ): void {
745  $page->assertWiki( PageIdentity::LOCAL );
746 
747  $this->cache[CacheKeyHelper::getKeyForPage( $page )]['oldRestrictions'] =
748  $oldRestrictions;
749  }
750 
751 }
Page\PageIdentity
Interface for objects (potentially) representing an editable wiki page.
Definition: PageIdentity.php:64
MediaWiki\Permissions\RestrictionStore\loadRestrictions
loadRestrictions(PageIdentity $page, int $flags=IDBAccessObject::READ_NORMAL, ?string $oldRestrictions=null)
Load restrictions from page.page_restrictions and the page_restrictions table.
Definition: RestrictionStore.php:343
LinkCache
Cache for article titles (prefixed DB keys) and ids linked from one source.
Definition: LinkCache.php:40
Wikimedia\Rdbms\Database
Relational database abstraction object.
Definition: Database.php:52
MediaWiki\Permissions\RestrictionStore\$linkCache
LinkCache $linkCache
Definition: RestrictionStore.php:48
MediaWiki\Permissions\RestrictionStore\getCascadeProtectionSources
getCascadeProtectionSources(PageIdentity $page)
Cascading protection: Get the source of any cascading restrictions on this page.
Definition: RestrictionStore.php:590
MediaWiki\Permissions\RestrictionStore\$pageStore
PageStore $pageStore
Definition: RestrictionStore.php:60
CommentStore
Handle database storage of comments such as edit summaries and log reasons.
Definition: CommentStore.php:42
Page\PageIdentity\getId
getId( $wikiId=self::LOCAL)
Returns the page ID.
MediaWiki\Permissions\RestrictionStore\getRestrictionExpiry
getRestrictionExpiry(PageIdentity $page, string $action)
Get the expiry time for the restriction against a given action.
Definition: RestrictionStore.php:148
MediaWiki\Permissions\RestrictionStore\$hookContainer
HookContainer $hookContainer
Definition: RestrictionStore.php:54
MediaWiki\Permissions\RestrictionStore\areRestrictionsLoaded
areRestrictionsLoaded(PageIdentity $page)
Definition: RestrictionStore.php:688
$res
$res
Definition: testCompression.php:57
IDBAccessObject
Interface for database access objects.
Definition: IDBAccessObject.php:57
MediaWiki\Permissions\RestrictionStore\$cache
array[] $cache
Caching various restrictions data in the following format: cache key => [ string[] restrictions => re...
Definition: RestrictionStore.php:74
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
Title\castFromPageIdentity
static castFromPageIdentity(?PageIdentity $pageIdentity)
Return a Title for a given PageIdentity.
Definition: Title.php:331
$dbr
$dbr
Definition: testCompression.php:54
MediaWiki\Permissions\RestrictionStore\getCreateProtection
getCreateProtection(PageIdentity $page)
Is this title subject to protection against creation?
Definition: RestrictionStore.php:171
NS_SPECIAL
const NS_SPECIAL
Definition: Defines.php:53
MediaWiki\Permissions\RestrictionStore\registerOldRestrictions
registerOldRestrictions(PageIdentity $page, string $oldRestrictions)
Register legacy restrictions from page.page_restrictions.
Definition: RestrictionStore.php:744
MediaWiki\Permissions\RestrictionStore\$options
ServiceOptions $options
Definition: RestrictionStore.php:39
Wikimedia\Rdbms\Database\getCacheSetOptions
static getCacheSetOptions(?IDatabase ... $dbs)
Merge the result of getSessionLagStatus() for several DBs using the most pessimistic values to estima...
Definition: Database.php:5240
MediaWiki\Config\ServiceOptions
A class for passing options to services.
Definition: ServiceOptions.php:27
Page\PageReference\getNamespace
getNamespace()
Returns the page's namespace number.
MediaWiki\Permissions\RestrictionStore\$hookRunner
HookRunner $hookRunner
Definition: RestrictionStore.php:57
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:1694
DBAccessObjectUtils
Helper class for DAO classes.
Definition: DBAccessObjectUtils.php:29
MediaWiki\Permissions\RestrictionStore\listAllRestrictionTypes
listAllRestrictionTypes(bool $exists=true)
Get a filtered list of all restriction types supported by this wiki.
Definition: RestrictionStore.php:321
MediaWiki\DAO\WikiAwareEntity\assertWiki
assertWiki( $wikiId)
Throws if $wikiId is different from the return value of getWikiId().
MediaWiki\Cache\CacheKeyHelper\getKeyForPage
static getKeyForPage( $page)
Definition: CacheKeyHelper.php:59
DBAccessObjectUtils\hasFlags
static hasFlags( $bitfield, $flags)
Definition: DBAccessObjectUtils.php:35
Page\PageReference\getDBkey
getDBkey()
Get the page title in DB key form.
MediaWiki\Permissions\RestrictionStore\isProtected
isProtected(PageIdentity $page, string $action='')
Does the title correspond to a protected article?
Definition: RestrictionStore.php:241
DB_PRIMARY
const DB_PRIMARY
Definition: defines.php:27
MediaWiki\Permissions\RestrictionStore\deleteCreateProtection
deleteCreateProtection(PageIdentity $page)
Remove any title creation protection due to page existing.
Definition: RestrictionStore.php:193
WANObjectCache
Multi-datacenter aware caching interface.
Definition: WANObjectCache.php:137
MediaWiki\Permissions\RestrictionStore\isCascadeProtected
isCascadeProtected(PageIdentity $page)
Cascading protection: Return true if cascading restrictions apply to this page, false if not.
Definition: RestrictionStore.php:280
MediaWiki\Permissions\RestrictionStore\$commentStore
CommentStore $commentStore
Definition: RestrictionStore.php:51
MediaWiki\Permissions\RestrictionStore\getAllRestrictions
getAllRestrictions(PageIdentity $page)
Returns the restricted actions and their restrictions for the specified page.
Definition: RestrictionStore.php:130
MediaWiki\Permissions\RestrictionStore\CONSTRUCTOR_OPTIONS
const CONSTRUCTOR_OPTIONS
Definition: RestrictionStore.php:31
MediaWiki\Permissions\RestrictionStore\areRestrictionsCascading
areRestrictionsCascading(PageIdentity $page)
Checks if restrictions are cascading for the current page.
Definition: RestrictionStore.php:712
MediaWiki\Permissions\RestrictionStore\__construct
__construct(ServiceOptions $options, WANObjectCache $wanCache, ILoadBalancer $loadBalancer, LinkCache $linkCache, CommentStore $commentStore, HookContainer $hookContainer, PageStore $pageStore)
Definition: RestrictionStore.php:85
MediaWiki\Permissions\RestrictionStore\$wanCache
WANObjectCache $wanCache
Definition: RestrictionStore.php:42
MediaWiki\$action
string $action
Cache what action this request is.
Definition: MediaWiki.php:45
Title
Represents a title within MediaWiki.
Definition: Title.php:47
MediaWiki\Permissions\RestrictionStore\isSemiProtected
isSemiProtected(PageIdentity $page, string $action='edit')
Is this page "semi-protected" - the only protection levels are listed in $wgSemiprotectedRestrictionL...
Definition: RestrictionStore.php:213
MediaWiki\Permissions\RestrictionStore\getRestrictions
getRestrictions(PageIdentity $page, string $action)
Returns list of restrictions for specified page.
Definition: RestrictionStore.php:116
Page\PageIdentity\exists
exists()
Checks if the page currently exists.
MediaWiki\Permissions\RestrictionStore\flushRestrictions
flushRestrictions(PageIdentity $page)
Flush the protection cache in this object and force reload from the database.
Definition: RestrictionStore.php:728
MediaWiki\Cache\CacheKeyHelper
Helper class for mapping value objects representing basic entities to cache keys.
Definition: CacheKeyHelper.php:43
Page\PageIdentityValue
Immutable value object representing a page identity.
Definition: PageIdentityValue.php:41
MediaWiki\Permissions\RestrictionStore\convertOldRestrictions
convertOldRestrictions(string $oldRestrictions)
Given a string formatted like the legacy page.page_restrictions field, return an array of restriction...
Definition: RestrictionStore.php:511
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition: HookContainer.php:45
MediaWiki\HookContainer\HookRunner
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:557
NS_FILE
const NS_FILE
Definition: Defines.php:70
MediaWiki\Permissions\RestrictionStore\areCascadeProtectionSourcesLoaded
areCascadeProtectionSourcesLoaded(PageIdentity $page)
Determines whether cascading protection sources have already been loaded from the database.
Definition: RestrictionStore.php:700
MediaWiki\Permissions\RestrictionStore
Class RestrictionStore.
Definition: RestrictionStore.php:28
MediaWiki\Permissions\RestrictionStore\getCascadeProtectionSourcesInternal
getCascadeProtectionSourcesInternal(PageIdentity $page, bool $shortCircuit=false)
Cascading protection: Get the source of any cascading restrictions on this page.
Definition: RestrictionStore.php:604
Page\PageStore
Definition: PageStore.php:29
Page\PageIdentity\canExist
canExist()
Checks whether this PageIdentity represents a "proper" page, meaning that it could exist as an editab...
MediaWiki\Permissions\RestrictionStore\$loadBalancer
ILoadBalancer $loadBalancer
Definition: RestrictionStore.php:45
MediaWiki\Permissions\RestrictionStore\loadRestrictionsFromRows
loadRestrictionsFromRows(PageIdentity $page, array $rows, ?string $oldRestrictions=null)
Compiles list of active page restrictions for this existing page.
Definition: RestrictionStore.php:436
Wikimedia\Rdbms\ILoadBalancer
Database cluster connection, tracking, load balancing, and transaction manager interface.
Definition: ILoadBalancer.php:81
MediaWiki\Permissions\RestrictionStore\listApplicableRestrictionTypes
listApplicableRestrictionTypes(PageIdentity $page)
Returns restriction types for the current page.
Definition: RestrictionStore.php:292
MediaWiki\Config\ServiceOptions\assertRequiredOptions
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
Definition: ServiceOptions.php:71
MediaWiki\Permissions
Definition: Authority.php:21
MediaWiki\Permissions\RestrictionStore\getCreateProtectionInternal
getCreateProtectionInternal(PageIdentity $page)
Fetch title protection settings.
Definition: RestrictionStore.php:539
$type
$type
Definition: testCompression.php:52