summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/PropertySpecificationReqExaminer.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/PropertySpecificationReqExaminer.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/PropertySpecificationReqExaminer.php295
1 files changed, 295 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/PropertySpecificationReqExaminer.php b/www/wiki/extensions/SemanticMediaWiki/src/PropertySpecificationReqExaminer.php
new file mode 100644
index 00000000..9f184a17
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/PropertySpecificationReqExaminer.php
@@ -0,0 +1,295 @@
+<?php
+
+namespace SMW;
+
+use SMW\PropertyAnnotators\MandatoryTypePropertyAnnotator;
+use SMW\Protection\ProtectionValidator;
+use SMWDataItem as DataItem;
+
+/**
+ * Examines codified requirements for listed types of property specifications which
+ * in case of a violation returns a message with the details of that violation.
+ *
+ * @license GNU GPL v2+
+ * @since 2.5
+ *
+ * @author mwjames
+ */
+class PropertySpecificationReqExaminer {
+
+ /**
+ * @var Store
+ */
+ private $store;
+
+ /**
+ * @var ProtectionValidator
+ */
+ private $protectionValidator;
+
+ /**
+ * @var SemanticData
+ */
+ private $semanticData;
+
+ /**
+ * @var boolean
+ */
+ private $changePropagationProtection = true;
+
+ /**
+ * @var DataItemFactory
+ */
+ private $dataItemFactory;
+
+ /**
+ * @var boolean
+ */
+ private $reqLock = false;
+
+ /**
+ * @since 2.5
+ *
+ * @param Store $store
+ * @param ProtectionValidator $protectionValidator
+ */
+ public function __construct( Store $store, ProtectionValidator $protectionValidator ) {
+ $this->store = $store;
+ $this->protectionValidator = $protectionValidator;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param SemanticData|null $semanticData
+ */
+ public function setSemanticData( SemanticData $semanticData = null ) {
+ $this->semanticData = $semanticData;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param boolean $changePropagationProtection
+ */
+ public function setChangePropagationProtection( $changePropagationProtection ) {
+ $this->changePropagationProtection = (bool)$changePropagationProtection;
+ }
+
+ /**
+ * Whether a specific property requires a lock nor not.
+ *
+ * @since 3.0
+ *
+ * @param boolean
+ */
+ public function reqLock() {
+ return $this->reqLock;
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param DIProperty $property
+ *
+ * @return array|null
+ */
+ public function check( DIProperty $property ) {
+
+ $subject = $property->getCanonicalDiWikiPage();
+ $title = $subject->getTitle();
+
+ $semanticData = $this->store->getSemanticData( $subject );
+
+ if ( $this->semanticData === null ) {
+ $this->semanticData = $semanticData;
+ }
+
+ $this->reqLock = false;
+ $this->dataItemFactory = new DataItemFactory();
+
+ if ( $semanticData->hasProperty( new DIProperty( DIProperty::TYPE_CHANGE_PROP ) ) ) {
+ $severity = $this->changePropagationProtection ? 'error' : 'warning';
+ $this->reqLock = true;
+ return [
+ $severity,
+ 'smw-property-req-violation-change-propagation-locked-' . $severity,
+ $property->getLabel()
+ ];
+ }
+
+ if ( $this->reqLock === false && $this->protectionValidator->hasCreateProtection( $title ) ) {
+ $msg = 'smw-create-protection';
+
+ if ( $title->exists() ) {
+ $msg = 'smw-create-protection-exists';
+ }
+
+ return [
+ 'warning',
+ $msg,
+ $property->getLabel(),
+ $this->protectionValidator->getCreateProtectionRight()
+ ];
+ }
+
+ if ( $this->reqLock === false && $this->protectionValidator->hasEditProtection( $title ) ) {
+ return [
+ $property->isUserDefined() ? 'error' : 'warning',
+ 'smw-edit-protection',
+ $this->protectionValidator->getEditProtectionRight()
+ ];
+ }
+
+ if ( !$property->isUserDefined() ) {
+ return $this->checkTypeForPredefinedProperty( $property );
+ }
+
+ $type = $property->findPropertyTypeID();
+
+ if ( $type === '_ref_rec' || $type === '_rec' ) {
+ return $this->checkFieldList( $property );
+ }
+
+ if ( $type === '_eid' ) {
+ return $this->checkExternalFormatterUri( $property );
+ }
+
+ if ( $type === '_geo' ) {
+ return $this->checkMaps( $property );
+ }
+
+ if ( $this->semanticData->getOption( MandatoryTypePropertyAnnotator::IMPO_REMOVED_TYPE ) ) {
+ return $this->checkImportedVocabType( $property );
+ }
+ }
+
+ /**
+ * A violation occurs when a predefined property contains a `Has type` annotation
+ * that is incompatible with the default type.
+ */
+ private function checkTypeForPredefinedProperty( $property ) {
+
+ if ( $property->getKey() === '_EDIP' ) {
+ return $this->checkEditProtectionRight( $property );
+ }
+
+ if ( !$this->semanticData->hasProperty( $this->dataItemFactory->newDIProperty( '_TYPE' ) ) ) {
+ return;
+ }
+
+ $typeValues = $this->semanticData->getPropertyValues(
+ $this->dataItemFactory->newDIProperty( '_TYPE' )
+ );
+
+ if ( $typeValues !== [] ) {
+ list( $url, $type ) = explode( "#", end( $typeValues )->getSerialization() );
+ }
+
+ if ( DataTypeRegistry::getInstance()->isEqualByType( $type, $property->findPropertyTypeID() ) ) {
+ return;
+ }
+
+ $prop = $this->dataItemFactory->newDIProperty( $type );
+
+ return [
+ 'error',
+ 'smw-property-req-violation-predefined-type',
+ $property->getCanonicalLabel(),
+ $prop->getCanonicalLabel()
+ ];
+ }
+
+ /**
+ * Examines whether the setting `smwgEditProtectionRight` contains an appropriate
+ * value or is disabled in order for the `Is edit protected` property to function.
+ */
+ private function checkEditProtectionRight( $property ) {
+
+ if ( $this->protectionValidator->getEditProtectionRight() !== false ) {
+ return;
+ }
+
+ return [
+ 'warning',
+ 'smw-edit-protection-disabled',
+ $property->getCanonicalLabel()
+ ];
+ }
+
+ /**
+ * A violation occurs when a Reference or Record typed property does not denote
+ * a `Has fields` declaration.
+ */
+ private function checkFieldList( $property ) {
+
+ if ( $this->semanticData->hasProperty( $this->dataItemFactory->newDIProperty( '_LIST' ) ) ) {
+ return;
+ }
+
+ $prop = $this->dataItemFactory->newDIProperty( $property->findPropertyTypeID() );
+
+ return [
+ 'error',
+ 'smw-property-req-violation-missing-fields',
+ $property->getLabel(),
+ $prop->getCanonicalLabel()
+ ];
+ }
+
+ /**
+ * A violation occurs when the External Identifier typed property does not declare
+ * a `External formatter URI` declaration.
+ */
+ private function checkExternalFormatterUri( $property ) {
+
+ if ( $this->semanticData->hasProperty( $this->dataItemFactory->newDIProperty( '_PEFU' ) ) ) {
+ return;
+ }
+
+ return [
+ 'error',
+ 'smw-property-req-violation-missing-formatter-uri',
+ $property->getLabel()
+ ];
+ }
+
+ private function checkMaps( $property ) {
+
+ if ( defined( 'SM_VERSION' ) ) {
+ return;
+ }
+
+ return [
+ 'error',
+ 'smw-property-req-violation-missing-maps-extension',
+ $property->getLabel()
+ ];
+ }
+
+ /**
+ * A violation occurs when the `Imported from` property detects an incompatible
+ * `Has type` declaration.
+ */
+ private function checkImportedVocabType( $property ) {
+
+ $typeValues = $this->semanticData->getPropertyValues(
+ $this->dataItemFactory->newDIProperty( '_TYPE' )
+ );
+
+ $dataItem = $this->semanticData->getOption(
+ MandatoryTypePropertyAnnotator::IMPO_REMOVED_TYPE
+ );
+
+ if ( $dataItem instanceof DataItem && end( $typeValues )->equals( $dataItem ) ) {
+ return;
+ }
+
+ return [
+ 'warning',
+ 'smw-property-req-violation-import-type',
+ $property->getLabel()
+ ];
+ }
+
+}