summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/PropertyRegistry.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/PropertyRegistry.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/PropertyRegistry.php499
1 files changed, 499 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/PropertyRegistry.php b/www/wiki/extensions/SemanticMediaWiki/src/PropertyRegistry.php
new file mode 100644
index 00000000..ab5f521a
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/PropertyRegistry.php
@@ -0,0 +1,499 @@
+<?php
+
+namespace SMW;
+
+/**
+ * @license GNU GPL v2+
+ * @since 2.1
+ *
+ * @author mwjames
+ * @author Markus Krötzsch
+ */
+class PropertyRegistry {
+
+ /**
+ * @var PropertyRegistry
+ */
+ private static $instance = null;
+
+ /**
+ * @var PropertyLabelFinder
+ */
+ private $propertyLabelFinder = null;
+
+ /**
+ * Array for assigning types to predefined properties. Each
+ * property is associated with an array with the following
+ * elements:
+ *
+ * * ID of datatype to be used for this property
+ *
+ * * Boolean, stating if this property is shown in Factbox, Browse, and
+ * similar interfaces; (note that this is only relevant if the
+ * property can be displayed at all, i.e. has a translated label in
+ * the wiki language; invisible properties are never shown).
+ *
+ * @var array
+ */
+ private $propertyList = [];
+
+ /**
+ * @var string[]
+ */
+ private $datatypeLabels = [];
+
+ /**
+ * @var string[]
+ */
+ private $propertyDescriptionMsgKeys = [];
+
+ /**
+ * @var PropertyAliasFinder
+ */
+ private $propertyAliasFinder;
+
+ /**
+ * @var string[]
+ */
+ private $dataTypePropertyExemptionList = [];
+
+ /**
+ * @since 2.1
+ *
+ * @return PropertyRegistry
+ */
+ public static function getInstance() {
+
+ if ( self::$instance !== null ) {
+ return self::$instance;
+ }
+
+ $applicationFactory = ApplicationFactory::getInstance();
+ $lang = Localizer::getInstance()->getLang();
+
+ $propertyAliasFinder = new PropertyAliasFinder(
+ $applicationFactory->getCache(),
+ $lang->getPropertyAliases(),
+ $lang->getCanonicalPropertyAliases()
+ );
+
+ $settings = $applicationFactory->getSettings();
+
+ self::$instance = new self(
+ DataTypeRegistry::getInstance(),
+ $applicationFactory->getPropertyLabelFinder(),
+ $propertyAliasFinder,
+ $settings->get( 'smwgDataTypePropertyExemptionList' )
+ );
+
+ self::$instance->initProperties(
+ TypesRegistry::getPropertyList(
+ $settings->isFlagSet( 'smwgCategoryFeatures', SMW_CAT_HIERARCHY )
+ )
+ );
+
+ return self::$instance;
+ }
+
+ /**
+ * @since 2.1
+ *
+ * @param DataTypeRegistry $datatypeRegistry
+ * @param PropertyLabelFinder $propertyLabelFinder
+ * @param PropertyAliasFinder $propertyAliasFinder
+ * @param array $dataTypePropertyExemptionList
+ */
+ public function __construct( DataTypeRegistry $datatypeRegistry, PropertyLabelFinder $propertyLabelFinder, PropertyAliasFinder $propertyAliasFinder, array $dataTypePropertyExemptionList = [] ) {
+
+ $this->datatypeLabels = $datatypeRegistry->getKnownTypeLabels();
+ $this->propertyLabelFinder = $propertyLabelFinder;
+ $this->propertyAliasFinder = $propertyAliasFinder;
+
+ // To get an index access
+ $this->dataTypePropertyExemptionList = array_flip( $dataTypePropertyExemptionList );
+
+ foreach ( $this->datatypeLabels as $id => $label ) {
+
+ if ( isset( $this->dataTypePropertyExemptionList[$label] ) ) {
+ continue;
+ }
+
+ $this->registerPropertyLabel( $id, $label );
+ }
+
+ foreach ( $datatypeRegistry->getKnownTypeAliases() as $alias => $id ) {
+
+ if ( isset( $this->dataTypePropertyExemptionList[$alias] ) ) {
+ continue;
+ }
+
+ $this->registerPropertyAlias( $id, $alias );
+ }
+ }
+
+ /**
+ * @since 2.1
+ */
+ public static function clear() {
+ self::$instance = null;
+ }
+
+ /**
+ * @since 2.1
+ *
+ * @return array
+ */
+ public function getPropertyList() {
+ return $this->propertyList;
+ }
+
+ /**
+ * @since 2.1
+ *
+ * @return array
+ */
+ public function getKnownPropertyAliases() {
+ return $this->propertyAliasFinder->getKnownPropertyAliases();
+ }
+
+ /**
+ * A method for registering/overwriting predefined properties for SMW.
+ * It should be called from within the hook 'smwInitProperties' only.
+ * IDs should start with three underscores "___" to avoid current and
+ * future confusion with SMW built-ins.
+ *
+ * @param string $id
+ * @param string $valueType SMW type id
+ * @param string|bool $label user label or false (internal property)
+ * @param boolean $isVisible only used if label is given, see isShown()
+ * @param boolean $isAnnotable
+ */
+ public function registerProperty( $id, $valueType, $label = false, $isVisible = false, $isAnnotable = true ) {
+
+ $this->propertyList[$id] = [ $valueType, $isVisible, $isAnnotable ];
+
+ if ( $label !== false ) {
+ $this->registerPropertyLabel( $id, $label );
+ }
+ }
+
+ /**
+ * Add a new alias label to an existing property ID. Note that every ID
+ * should have a primary label, either provided by SMW or registered
+ * with registerProperty().
+ *
+ * @param $id string id of a property
+ * @param $label string alias label for the property
+ *
+ * @note Always use registerProperty() for the first label. No property
+ * that has used "false" for a label on registration should have an
+ * alias.
+ */
+ public function registerPropertyAlias( $id, $label ) {
+ $this->propertyAliasFinder->registerAliasByFixedLabel( $id, $label );
+ }
+
+ /**
+ * Register an alias using a message key to allow fetching localized
+ * labels dynamically (for when the user language is changed etc).
+ *
+ * @since 2.4
+ *
+ * @param string $id
+ * @param string $msgKey
+ */
+ public function registerPropertyAliasByMsgKey( $id, $msgKey ) {
+ $this->propertyAliasFinder->registerAliasByMsgKey( $id, $msgKey );
+ }
+
+ /**
+ * Register a description message key for allowing it to be displayed in a
+ * localized context.
+ *
+ * @since 2.5
+ *
+ * @param string $id
+ * @param string $msgKey
+ */
+ public function registerPropertyDescriptionByMsgKey( $id, $msgKey ) {
+ $this->propertyDescriptionMsgKeys[$id] = $msgKey;
+ }
+
+ /**
+ * @deprecated since 3.0, use PropertyRegistry::registerPropertyDescriptionByMsgKey
+ */
+ public function registerPropertyDescriptionMsgKeyById( $id, $msgKey ) {
+ $this->registerPropertyDescriptionByMsgKey( $id, $msgKey );
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param string $id
+ *
+ * @return string
+ */
+ public function findPropertyDescriptionMsgKeyById( $id ) {
+ return isset( $this->propertyDescriptionMsgKeys[$id] ) ? $this->propertyDescriptionMsgKeys[$id] : '';
+ }
+
+ /**
+ * Get the translated user label for a given internal property ID.
+ * Returns empty string for properties without a translation (these are
+ * usually internal, generated by SMW but not shown to the user).
+ *
+ * @note An empty string is returned for incomplete translation (language
+ * bug) or deliberately invisible property
+ *
+ * @since 2.1
+ *
+ * @param string $id
+ *
+ * @return string
+ */
+ public function findPropertyLabelById( $id ) {
+
+ // This is a hack but there is no other good way to make it work without
+ // open a whole new can of worms
+ // '__' indicates predefined properties of extensions that contain alias
+ // and translated labels and if available we want the translated label
+ if ( ( substr( $id, 0, 2 ) === '__' ) &&
+ ( $label = $this->propertyAliasFinder->findPropertyAliasById( $id ) ) ) {
+ return $label;
+ }
+
+ // core has dedicated files per language so the label is available over
+ // the invoked language
+ return $this->propertyLabelFinder->findPropertyLabelById( $id );
+ }
+
+ /**
+ * @since 2.4
+ *
+ * @param string $id
+ *
+ * @return string
+ */
+ public function findCanonicalPropertyLabelById( $id ) {
+ return $this->propertyLabelFinder->findCanonicalPropertyLabelById( $id );
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param string $id
+ * @param string $languageCode
+ *
+ * @return string
+ */
+ public function findPropertyLabelFromIdByLanguageCode( $id, $languageCode = '' ) {
+ return $this->propertyLabelFinder->findPropertyLabelFromIdByLanguageCode( $id, $languageCode );
+ }
+
+ /**
+ * @deprecated since 2.1 use findPropertyLabelById instead
+ */
+ public function findPropertyLabel( $id ) {
+ return $this->findPropertyLabelById( $id );
+ }
+
+ /**
+ * Get the type ID of a predefined property, or '' if the property
+ * is not predefined.
+ * The function is guaranteed to return a type ID for keys of
+ * properties where isUserDefined() returns false.
+ *
+ * @param string $id
+ *
+ * @return string
+ */
+ public function getPropertyValueTypeById( $id ) {
+
+ if ( $this->isRegistered( $id ) ) {
+ return $this->propertyList[$id][0];
+ }
+
+ return '';
+ }
+
+ /**
+ * @deprecated since 3.0, use PropertyRegistry::getPropertyValueTypeById instead
+ */
+ public function getPropertyTypeId( $id ) {
+ return $this->getPropertyValueTypeById( $id );
+ }
+
+ /**
+ * @deprecated since 2.1 use getPropertyValueTypeById instead
+ */
+ public function getPredefinedPropertyTypeId( $id ) {
+ return $this->getPropertyValueTypeById( $id );
+ }
+
+ /**
+ * Find and return the ID for the pre-defined property of the given
+ * local label. If the label does not belong to a pre-defined property,
+ * return false.
+ *
+ * @param string $label normalized property label
+ * @param boolean $useAlias determining whether to check if the label is an alias
+ *
+ * @return mixed string property ID or false
+ */
+ public function findPropertyIdByLabel( $label, $useAlias = true ) {
+
+ $id = $this->propertyLabelFinder->searchPropertyIdByLabel( $label );
+
+ if ( $id !== false ) {
+ return $id;
+ } elseif ( $useAlias && $this->propertyAliasFinder->findPropertyIdByAlias( $label ) ) {
+ return $this->propertyAliasFinder->findPropertyIdByAlias( $label );
+ }
+
+ return false;
+ }
+
+ /**
+ * @since 2.4
+ *
+ * @param string $label
+ * @param string $languageCode
+ *
+ * @return mixed string property ID or false
+ */
+ public function findPropertyIdFromLabelByLanguageCode( $label, $languageCode = '' ) {
+
+ $languageCode = mb_strtolower( trim( $languageCode ) );
+
+ // Match the canonical form
+ if ( $languageCode === '' ) {
+ return $this->findPropertyIdByLabel( $label );
+ }
+
+ $lang = Localizer::getInstance()->getLang(
+ $languageCode
+ );
+
+ // Language dep. stored as aliases
+ $aliases = $lang->getPropertyLabels() + $lang->getDatatypeLabels();
+
+ if ( ( $id = array_search( $label, $aliases ) ) !== false && !isset( $this->dataTypePropertyExemptionList[$label] ) ) {
+ return $id;
+ }
+
+ // Those are mostly from extension that register a msgKey as no dedicated
+ // lang. file exists; maybe this should be cached somehow?
+ foreach ( $this->propertyAliasFinder->getKnownPropertyAliasesByLanguageCode( $languageCode ) as $alias => $id ) {
+ if ( $label === $alias ) {
+ return $id;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param string $id
+ * @param string|null $languageCode
+ *
+ * @return string
+ */
+ public function findPreferredPropertyLabelFromIdByLanguageCode( $id, $languageCode = '' ) {
+
+ if ( $languageCode === false || $languageCode === '' ) {
+ $languageCode = Localizer::getInstance()->getUserLanguage()->getCode();
+ }
+
+ return $this->propertyLabelFinder->findPreferredPropertyLabelByLanguageCode( $id, $languageCode );
+ }
+
+ /**
+ * @deprecated since 2.1 use findPropertyIdByLabel instead
+ */
+ public function findPropertyId( $label, $useAlias = true ) {
+ return $this->findPropertyIdByLabel( $label, $useAlias );
+ }
+
+ /**
+ * @deprecated since 3.0 use isRegistered instead
+ */
+ public function isKnownPropertyId( $id ) {
+ return $this->isRegistered( $id );
+ }
+
+ /**
+ * @since 2.1
+ *
+ * @param string $id
+ *
+ * @return boolean
+ */
+ public function isRegistered( $id ) {
+ return isset( $this->propertyList[$id] ) || array_key_exists( $id, $this->propertyList );
+ }
+
+ /**
+ * @since 2.1
+ *
+ * @param string $id
+ *
+ * @return boolean
+ */
+ public function isVisible( $id ) {
+ return $this->isRegistered( $id ) ? $this->propertyList[$id][1] : false;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param string $id
+ *
+ * @return boolean
+ */
+ public function isAnnotable( $id ) {
+ return $this->isRegistered( $id ) ? $this->propertyList[$id][2] : false;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param string $id
+ *
+ * @return boolean
+ */
+ public function isDeclarative( $id ) {
+
+ if ( !$this->isRegistered( $id ) ) {
+ return false;
+ }
+
+ return isset( $this->propertyList[$id][3] ) ? $this->propertyList[$id][3] : false;
+ }
+
+ /**
+ * @note All ids must start with underscores. The translation for each ID,
+ * if any, is defined in the language files. Properties without translation
+ * cannot be entered by or displayed to users, whatever their "show" value
+ * below.
+ */
+ protected function initProperties( array $propertyList ) {
+
+ $this->propertyList = $propertyList;
+
+ foreach ( $this->datatypeLabels as $id => $label ) {
+ $this->propertyList[$id] = [ $id, true, true, false ];
+ }
+
+ // @deprecated since 2.1
+ \Hooks::run( 'smwInitProperties' );
+
+ \Hooks::run( 'SMW::Property::initProperties', [ $this ] );
+ }
+
+ private function registerPropertyLabel( $id, $label, $asCanonical = true ) {
+ $this->propertyLabelFinder->registerPropertyLabel( $id, $label, $asCanonical );
+ }
+
+}