summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/Protection/ProtectionValidator.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/Protection/ProtectionValidator.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/Protection/ProtectionValidator.php222
1 files changed, 222 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/Protection/ProtectionValidator.php b/www/wiki/extensions/SemanticMediaWiki/src/Protection/ProtectionValidator.php
new file mode 100644
index 00000000..ff8103ea
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/Protection/ProtectionValidator.php
@@ -0,0 +1,222 @@
+<?php
+
+namespace SMW\Protection;
+
+use Onoi\Cache\Cache;
+use SMW\CachedPropertyValuesPrefetcher;
+use SMW\DIProperty;
+use SMW\DIWikiPage;
+use SMW\RequestOptions;
+use Title;
+
+/**
+ * Handles protection validation.
+ *
+ * The lookup is cached using the `CachedPropertyValuesPrefetcher` to avoid a
+ * continued access to the Store or DB layer.
+ *
+ * @license GNU GPL v2+
+ * @since 2.5
+ *
+ * @author mwjames
+ */
+class ProtectionValidator {
+
+ /**
+ * Reference used in InMemoryPoolCache
+ */
+ const POOLCACHE_ID = 'protection.validator';
+
+ /**
+ * @var CachedPropertyValuesPrefetcher
+ */
+ private $cachedPropertyValuesPrefetcher;
+
+ /**
+ * @var Cache
+ */
+ private $intermediaryMemoryCache;
+
+ /**
+ * @var boolean|string
+ */
+ private $editProtectionRight = false;
+
+ /**
+ * @var boolean|string
+ */
+ private $createProtectionRight = false;
+
+ /**
+ * @var boolean|string
+ */
+ private $changePropagationProtection = true;
+
+ /**
+ * @since 2.5
+ *
+ * @param CachedPropertyValuesPrefetcher $cachedPropertyValuesPrefetcher
+ * @param Cache $intermediaryMemoryCache
+ */
+ public function __construct( CachedPropertyValuesPrefetcher $cachedPropertyValuesPrefetcher, Cache $intermediaryMemoryCache ) {
+ $this->cachedPropertyValuesPrefetcher = $cachedPropertyValuesPrefetcher;
+ $this->intermediaryMemoryCache = $intermediaryMemoryCache;
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param string|boolean $editProtectionRight
+ */
+ public function setEditProtectionRight( $editProtectionRight ) {
+ $this->editProtectionRight = $editProtectionRight;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @return string|false
+ */
+ public function getEditProtectionRight() {
+ return $this->editProtectionRight;
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param string|boolean $createProtectionRight
+ */
+ public function setCreateProtectionRight( $createProtectionRight ) {
+ $this->createProtectionRight = $createProtectionRight;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @return string|false
+ */
+ public function getCreateProtectionRight() {
+ return $this->createProtectionRight;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param boolean $changePropagationProtection
+ */
+ public function setChangePropagationProtection( $changePropagationProtection ) {
+ $this->changePropagationProtection = (bool)$changePropagationProtection;
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param DIWikiPage $subject
+ */
+ private function resetCacheBy( DIWikiPage $subject ) {
+ $this->cachedPropertyValuesPrefetcher->resetCacheBy( $subject );
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param Title $title
+ *
+ * @return boolean
+ */
+ public function hasEditProtectionOnNamespace( Title $title ) {
+ return $this->editProtectionRight && $this->checkProtection( DIWikiPage::newFromTitle( $title )->asBase() );
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param Title $title
+ *
+ * @return boolean
+ */
+ public function hasChangePropagationProtection( Title $title ) {
+
+ $subject = DIWikiPage::newFromTitle( $title )->asBase();
+ $namespace = $subject->getNamespace();
+
+ if ( ( $namespace !== SMW_NS_PROPERTY && $namespace !== NS_CATEGORY ) || $this->changePropagationProtection === false ) {
+ return false;
+ }
+
+ return $this->checkProtection( $subject, new DIProperty( '_CHGPRO' ) );
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param Title $title
+ *
+ * @return boolean
+ */
+ public function hasProtection( Title $title ) {
+ return $this->checkProtection( DIWikiPage::newFromTitle( $title )->asBase() );
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param Title $title
+ * @param Title $title
+ *
+ * @return boolean
+ */
+ public function hasCreateProtection( Title $title ) {
+ return $this->createProtectionRight && !$title->userCan( 'edit' );
+ }
+
+ /**
+ * @note There is not direct validation of the permission within this method,
+ * it is done by the Title::userCan when probing against the User and hooks
+ * that carry out the permission check including the validation provided by
+ * SMW's `PermissionPthValidator`.
+ *
+ * @since 2.5
+ *
+ * @param Title $title
+ *
+ * @return boolean
+ */
+ public function hasEditProtection( Title $title ) {
+ return !$title->userCan( 'edit' ) && $this->checkProtection( DIWikiPage::newFromTitle( $title )->asBase() );
+ }
+
+ private function checkProtection( $subject, $property = null ) {
+
+ if ( $property === null ) {
+ $property = new DIProperty( '_EDIP' );
+ }
+
+ $key = $subject->getHash() . $property->getKey();
+ $hasProtection = false;
+
+ if ( $this->intermediaryMemoryCache->contains( $key ) ) {
+ return $this->intermediaryMemoryCache->fetch( $key );
+ }
+
+ // Set editProtectionRight to influence the key to detect changes
+ // before the cache is evicted
+ $requestOptions = new RequestOptions();
+ $requestOptions->addExtraCondition( $this->editProtectionRight );
+
+ $dataItems = $this->cachedPropertyValuesPrefetcher->getPropertyValues(
+ $subject,
+ $property,
+ $requestOptions
+ );
+
+ if ( $dataItems !== null && $dataItems !== [] ) {
+ $hasProtection = $property->getKey() === '_EDIP' ? end( $dataItems )->getBoolean() : true;
+ }
+
+ $this->intermediaryMemoryCache->save( $key, $hasProtection );
+
+ return $hasProtection;
+ }
+
+}