Mwjames has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/89492


Change subject: Resolve violation of SoC in DataValuesFactory class
......................................................................

Resolve violation of SoC in DataValuesFactory class

Code coverage: 100%
CRAP: 21

SoC (separation of concerns) violation

DataType registration and DataValue factoring are two distinct tasks
and should not be mixed.

DataValuesFactory static classes are deprecated, use
DataTypeRegistry::getInstance()-> ... instead

Change-Id: I370262323c203cf480ac174acab6a1ebc366ac9e
---
M SemanticMediaWiki.classes.php
M SemanticMediaWiki.php
M docs/hooks.md
A includes/DataTypeRegistry.php
M includes/DataValueFactory.php
A tests/phpunit/includes/DataTypeRegistryTest.php
M tests/phpunit/includes/DataValueFactoryTest.php
7 files changed, 516 insertions(+), 254 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/SemanticMediaWiki 
refs/changes/92/89492/1

diff --git a/SemanticMediaWiki.classes.php b/SemanticMediaWiki.classes.php
index 9fb5bbf..c3751d5 100644
--- a/SemanticMediaWiki.classes.php
+++ b/SemanticMediaWiki.classes.php
@@ -34,6 +34,7 @@
        'SMW\SemanticData'          => 'includes/SMW_SemanticData.php',
        'SMWPageLister'             => 'includes/SMW_PageLister.php',
 
+       'SMW\DataTypeRegistry'      => 'includes/DataTypeRegistry.php',
        'SMWDataValueFactory'       => 'includes/DataValueFactory.php',
        'SMW\DataValueFactory'      => 'includes/DataValueFactory.php',
 
diff --git a/SemanticMediaWiki.php b/SemanticMediaWiki.php
index a863ed4..b7685ff 100644
--- a/SemanticMediaWiki.php
+++ b/SemanticMediaWiki.php
@@ -109,6 +109,7 @@
 class_alias( 'SMW\DIWikiPage', 'SMWDIWikiPage' );
 class_alias( 'SMW\DIProperty', 'SMWDIProperty' );
 class_alias( 'SMW\DISerializer', 'SMWDISerializer' );
+class_alias( 'SMW\DataValueFactory', 'SMWDataValueFactory' );
 
 // A flag used to indicate SMW defines a semantic extension type for extension 
credits.
 // @deprecated, removal in SMW 1.11
diff --git a/docs/hooks.md b/docs/hooks.md
index 0b94c7c..03e2e28 100644
--- a/docs/hooks.md
+++ b/docs/hooks.md
@@ -29,7 +29,20 @@
        return true;
 };
 ```
-Before 1.9 was called smwUpdatePropertySubjects with a different interface.
+Before 1.9 it was called smwUpdatePropertySubjects with a different interface.
+
+### SMW::DataType::initTypes (SMW 1.9)
+Adds support for additional DataTypes.
+
+```php
+$GLOBALS['wgHooks']['SMW::DataType::initTypes'][] = function () {
+
+       DataTypeRegistry::getInstance()->registerDatatype( '_foo', 
'\SMW\FooValue', \SMW\DataItem::TYPE_GEO );
+
+       return true;
+};
+```
+Before 1.9 it was called smwInitDatatypes.
 
 ## SQLStore
 ### SMW::SQLStore::updatePropertyTableDefinitions (SMW 1.9)
diff --git a/includes/DataTypeRegistry.php b/includes/DataTypeRegistry.php
new file mode 100644
index 0000000..53b9128
--- /dev/null
+++ b/includes/DataTypeRegistry.php
@@ -0,0 +1,357 @@
+<?php
+
+namespace SMW;
+
+use SMWDataItem as DataItem;
+
+/**
+ * DataTypes registry class
+ *
+ * @author Markus Krötzsch
+ * @author Jeroen De Dauw
+ *
+ * @file
+ * @ingroup SMWDataValues
+ */
+
+/**
+ * Registry class that manages registration data for datatypes, and
+ * provides various methods to access this information.
+ *
+ * @ingroup SMWDataValues
+ */
+class DataTypeRegistry {
+
+       /** DataTypeRegistry */
+       protected static $instance = null;
+
+       /**
+        * Array of type labels indexed by type ids. Used for datatype 
resolution.
+        *
+        * @var array
+        */
+       private $typeLabels;
+
+       /**
+        * Array of ids indexed by type aliases. Used for datatype resolution.
+        *
+        * @var array
+        */
+       private $typeAliases;
+
+       /**
+        * Array of class names for creating new SMWDataValue, indexed by type
+        * id.
+        *
+        * @var array of string
+        */
+       private $typeClasses;
+
+       /**
+        * Array of data item classes, indexed by type id.
+        *
+        * @var array of integer
+        */
+       private $typeDataItemIds;
+
+       /**
+        * Array of default types to use for making datavalues for dataitems.
+        *
+        * @var array of string
+        */
+       private $defaultDataItemTypeIds = array(
+               DataItem::TYPE_BLOB => '_txt', // Text type
+               DataItem::TYPE_URI => '_uri', // URL/URI type
+               DataItem::TYPE_WIKIPAGE => '_wpg', // Page type
+               DataItem::TYPE_NUMBER => '_num', // Number type
+               DataItem::TYPE_TIME => '_dat', // Time type
+               DataItem::TYPE_BOOLEAN => '_boo', // Boolean type
+               DataItem::TYPE_CONTAINER => '_rec', // Value list type 
(replacing former nary properties)
+               DataItem::TYPE_GEO => '_geo', // Geographical coordinates
+               DataItem::TYPE_CONCEPT => '__con', // Special concept page type
+               DataItem::TYPE_PROPERTY => '__pro', // Property type
+               // If either of the following two occurs, we want to see a PHP 
error:
+               //DataItem::TYPE_NOTYPE => '',
+               //DataItem::TYPE_ERROR => '',
+       );
+
+       /**
+        * Returns a DataTypeRegistry instance
+        *
+        * @since 1.9
+        *
+        * @return DataTypeRegistry
+        */
+       public static function getInstance() {
+
+               if ( self::$instance === null ) {
+                       self::$instance = new self();
+                       self::$instance->initDatatypes();
+               }
+
+               return self::$instance;
+       }
+
+       /**
+        * Resets the DataTypeRegistry instance
+        *
+        * @since 1.9
+        */
+       public static function clear() {
+               self::$instance = null;
+       }
+
+       /**
+        * Get the preferred data item ID for a given type. The ID defines the
+        * appropriate data item class for processing data of this type. See
+        * DataItem for possible values.
+        *
+        * @note SMWDIContainer is a pseudo dataitem type that is used only in
+        * data input methods, but not for storing data. Types that work with
+        * SMWDIContainer use SMWDIWikiPage as their DI type. (Since SMW 1.8)
+        *
+        * @param $typeId string id string for the given type
+        * @return integer data item ID
+        */
+       public function getDataItemId( $typeId ) {
+
+               if ( isset( $this->typeDataItemIds[ $typeId ] ) ) {
+                       return $this->typeDataItemIds[ $typeId ];
+               } else {
+                       return DataItem::TYPE_NOTYPE;
+               }
+
+       }
+
+       /**
+        * A function for registering/overwriting datatypes for SMW. Should be
+        * called from within the hook 'smwInitDatatypes'.
+        *
+        * @param $id string type ID for which this datatype is registered
+        * @param $className string name of the according subclass of 
SMWDataValue
+        * @param $dataItemId integer ID of the data item class that this data 
value uses, see DataItem
+        * @param $label mixed string label or false for types that cannot be 
accessed by users
+        */
+       public function registerDatatype( $id, $className, $dataItemId, $label 
= false ) {
+
+               $this->typeClasses[$id] = $className;
+               $this->typeDataItemIds[$id] = $dataItemId;
+
+               if ( $label != false ) {
+                       $this->typeLabels[$id] = $label;
+               }
+       }
+
+       /**
+        * Add a new alias label to an existing datatype id. Note that every ID
+        * should have a primary label, either provided by SMW or registered 
with
+        * registerDatatype(). This function should be called from within the 
hook
+        * 'smwInitDatatypes'.
+        *
+        * @param string $id
+        * @param string $label
+        */
+       public function registerDatatypeAlias( $id, $label ) {
+               $this->typeAliases[ $label ] = $id;
+       }
+
+       /**
+        * Look up the ID that identifies the datatype of the given label
+        * internally. This id is used for all internal operations. If the
+        * label does not bleong to a known type, the empty string is returned.
+        *
+        * This method may or may not take aliases into account, depeding on
+        * the parameter $useAlias.
+        *
+        * @param string $label
+        * @param boolean $useAlias
+        * @return string
+        */
+       public function findTypeID( $label, $useAlias = true ) {
+
+               $id = array_search( $label, $this->typeLabels );
+
+               if ( $id !== false ) {
+                       return $id;
+               } elseif ( ( $useAlias ) && ( array_key_exists( $label, 
$this->typeAliases ) ) ) {
+                       return $this->typeAliases[ $label ];
+               } else {
+                       return '';
+               }
+       }
+
+       /**
+        * Get the translated user label for a given internal ID. If the ID does
+        * not have a label associated with it in the current language, the
+        * empty string is returned. This is the case both for internal type ids
+        * and for invalid (unkown) type ids, so this method cannot be used to
+        * distinguish the two.
+        *
+        * @param string $id
+        */
+       public function findTypeLabel( $id ) {
+
+               if ( isset( $this->typeLabels[ $id ] ) ) {
+                       return $this->typeLabels[ $id ];
+               } else { // internal type without translation to user space;
+                       // might also happen for historic types after an 
upgrade --
+                       // alas, we have no idea what the former label would 
have been
+                       return '';
+               }
+
+       }
+
+       /**
+        * Return an array of all labels that a user might specify as the type 
of
+        * a property, and that are internal (i.e. not user defined). No labels 
are
+        * returned for internal types without user labels (e.g. the special 
types
+        * for some special properties), and for user defined types.
+        *
+        * @return array
+        */
+       public function getKnownTypeLabels() {
+               return $this->typeLabels;
+       }
+
+       /**
+        * ...
+        *
+        * @since 1.9
+        */
+       public function getDefaultDataItemTypeId( $diType ) {
+               return $this->defaultDataItemTypeIds[ $diType ];
+       }
+
+       /**
+        * ...
+        *
+        * @since 1.9
+        *
+        * @param $id string type ID for which this datatype is registered
+        */
+       public function getDataTypeClassById( $typeId ) {
+
+               if ( $this->hasDataTypeClassById( $typeId ) ) {
+                       return $this->typeClasses[ $typeId ];
+               }
+
+               return null;
+       }
+
+       /**
+        * Whether a datatype class is registered for a particular typeId
+        *
+        * @since 1.9
+        *
+        * @param $id string type ID for which this datatype is registered
+        */
+       public function hasDataTypeClassById( $typeId ) {
+               return isset( $this->typeClasses[ $typeId ] );
+       }
+
+       /**
+        * Gather all available datatypes and label<=>id<=>datatype
+        * associations. This method is called before most methods of this
+        * factory.
+        */
+       protected function initDatatypes() {
+
+               // FIXME Eliminate global variable
+
+               /**
+                * @var SMWLanguage $smwgContLang
+                */
+               global $smwgContLang;
+
+               if ( is_array( $this->typeLabels ) ) {
+                       return; // init happened before
+               }
+
+               $this->typeLabels = $smwgContLang->getDatatypeLabels();
+               $this->typeAliases = $smwgContLang->getDatatypeAliases();
+
+               // Setup built-in datatypes.
+               // NOTE: all ids must start with underscores, where two 
underscores indicate
+               // truly internal (non user-acessible types). All others should 
also get a
+               // translation in the language files, or they won't be 
available for users.
+               $this->typeClasses = array(
+                       '_txt'  => 'SMWStringValue', // Text type
+                       '_cod'  => 'SMWStringValue', // Code type
+                       '_str'  => 'SMWStringValue', // DEPRECATED Will vanish 
after SMW 1.9; use '_txt'
+                       '_ema'  => 'SMWURIValue', // Email type
+                       '_uri'  => 'SMWURIValue', // URL/URI type
+                       '_anu'  => 'SMWURIValue', // Annotation URI type
+                       '_tel'  => 'SMWURIValue', // Phone number (URI) type
+                       '_wpg'  => 'SMWWikiPageValue', // Page type
+                       '_wpp'  => 'SMWWikiPageValue', // Property page type 
TODO: make available to user space
+                       '_wpc'  => 'SMWWikiPageValue', // Category page type 
TODO: make available to user space
+                       '_wpf'  => 'SMWWikiPageValue', // Form page type for 
Semantic Forms
+                       '_num'  => 'SMWNumberValue', // Number type
+                       '_tem'  => 'SMWTemperatureValue', // Temperature type
+                       '_dat'  => 'SMWTimeValue', // Time type
+                       '_boo'  => 'SMWBoolValue', // Boolean type
+                       '_rec'  => 'SMWRecordValue', // Value list type 
(replacing former nary properties)
+                       '_qty'  => 'SMWQuantityValue', // Type for numbers with 
units of measurement
+                       // Special types are not avaialble directly for users 
(and have no local language name):
+                       '__typ' => 'SMWTypesValue', // Special type page type
+                       '__pls' => 'SMWPropertyListValue', // Special type list 
for decalring _rec properties
+                       '__con' => 'SMWConceptValue', // Special concept page 
type
+                       '__sps' => 'SMWStringValue', // Special string type
+                       '__spu' => 'SMWURIValue', // Special uri type
+                       '__sup' => 'SMWWikiPageValue', // Special subproperty 
type
+                       '__suc' => 'SMWWikiPageValue', // Special subcategory 
type
+                       '__spf' => 'SMWWikiPageValue', // Special Form page 
type for Semantic Forms
+                       '__sin' => 'SMWWikiPageValue', // Special instance of 
type
+                       '__red' => 'SMWWikiPageValue', // Special redirect type
+                       '__err' => 'SMWErrorValue', // Special error type
+                       '__imp' => 'SMWImportValue', // Special import 
vocabulary type
+                       '__pro' => 'SMWPropertyValue', // Property type 
(possibly predefined, no always based on a page)
+                       '__key' => 'SMWStringValue', // Sort key of a page
+               );
+
+               $this->typeDataItemIds = array(
+                       '_txt'  => DataItem::TYPE_BLOB, // Text type
+                       '_cod'  => DataItem::TYPE_BLOB, // Code type
+                       '_str'  => DataItem::TYPE_BLOB, // DEPRECATED Will 
vanish after SMW 1.9; use '_txt'
+                       '_ema'  => DataItem::TYPE_URI, // Email type
+                       '_uri'  => DataItem::TYPE_URI, // URL/URI type
+                       '_anu'  => DataItem::TYPE_URI, // Annotation URI type
+                       '_tel'  => DataItem::TYPE_URI, // Phone number (URI) 
type
+                       '_wpg'  => DataItem::TYPE_WIKIPAGE, // Page type
+                       '_wpp'  => DataItem::TYPE_WIKIPAGE, // Property page 
type TODO: make available to user space
+                       '_wpc'  => DataItem::TYPE_WIKIPAGE, // Category page 
type TODO: make available to user space
+                       '_wpf'  => DataItem::TYPE_WIKIPAGE, // Form page type 
for Semantic Forms
+                       '_num'  => DataItem::TYPE_NUMBER, // Number type
+                       '_tem'  => DataItem::TYPE_NUMBER, // Temperature type
+                       '_dat'  => DataItem::TYPE_TIME, // Time type
+                       '_boo'  => DataItem::TYPE_BOOLEAN, // Boolean type
+                       '_rec'  => DataItem::TYPE_WIKIPAGE, // Value list type 
(replacing former nary properties)
+                       '_geo'  => DataItem::TYPE_GEO, // Geographical 
coordinates
+                       '_gpo'  => DataItem::TYPE_BLOB, // Geographical polygon
+                       '_qty'  => DataItem::TYPE_NUMBER, // Type for numbers 
with units of measurement
+                       // Special types are not avaialble directly for users 
(and have no local language name):
+                       '__typ' => DataItem::TYPE_URI, // Special type page type
+                       '__pls' => DataItem::TYPE_BLOB, // Special type list 
for decalring _rec properties
+                       '__con' => DataItem::TYPE_CONCEPT, // Special concept 
page type
+                       '__sps' => DataItem::TYPE_BLOB, // Special string type
+                       '__spu' => DataItem::TYPE_URI, // Special uri type
+                       '__sup' => DataItem::TYPE_WIKIPAGE, // Special 
subproperty type
+                       '__suc' => DataItem::TYPE_WIKIPAGE, // Special 
subcategory type
+                       '__spf' => DataItem::TYPE_WIKIPAGE, // Special Form 
page type for Semantic Forms
+                       '__sin' => DataItem::TYPE_WIKIPAGE, // Special instance 
of type
+                       '__red' => DataItem::TYPE_WIKIPAGE, // Special redirect 
type
+                       '__err' => DataItem::TYPE_ERROR, // Special error type
+                       '__imp' => DataItem::TYPE_BLOB, // Special import 
vocabulary type
+                       '__pro' => DataItem::TYPE_PROPERTY, // Property type 
(possibly predefined, no always based on a page)
+                       '__key' => DataItem::TYPE_BLOB, // Sort key of a page
+               );
+
+               // Deprecated since 1.9
+               wfRunHooks( 'smwInitDatatypes' );
+
+               // Since 1.9
+               wfRunHooks( 'SMW::DataType::initTypes' );
+
+       }
+
+}
diff --git a/includes/DataValueFactory.php b/includes/DataValueFactory.php
index b6f0be0..4012d19 100644
--- a/includes/DataValueFactory.php
+++ b/includes/DataValueFactory.php
@@ -4,10 +4,8 @@
 
 use SMWDataItem;
 use SMWErrorValue;
-use SMWDIProperty;
 use SMWLanguage;
 use SMWPropertyValue;
-use SMWDIWikiPage;
 use SMWDIError;
 
 /**
@@ -29,62 +27,9 @@
  * property names. To create suitable datavalues for a given property, the
  * method newPropertyObjectValue() can be used.
  *
- * Other than this, the class manages registration data for datatypes, and
- * provides various methods to access this information.
- *
  * @ingroup SMWDataValues
  */
 class DataValueFactory {
-
-       /**
-        * Array of type labels indexed by type ids. Used for datatype 
resolution.
-        *
-        * @var array
-        */
-       static private $mTypeLabels;
-
-       /**
-        * Array of ids indexed by type aliases. Used for datatype resolution.
-        *
-        * @var array
-        */
-       static private $mTypeAliases;
-
-       /**
-        * Array of class names for creating new SMWDataValue, indexed by type
-        * id.
-        *
-        * @var array of string
-        */
-       static private $mTypeClasses;
-
-       /**
-        * Array of data item classes, indexed by type id.
-        *
-        * @var array of integer
-        */
-       static private $mTypeDataItemIds;
-
-       /**
-        * Array of default types to use for making datavalues for dataitems.
-        *
-        * @var array of string
-        */
-       static private $mDefaultDataItemTypeIds = array(
-               SMWDataItem::TYPE_BLOB => '_txt', // Text type
-               SMWDataItem::TYPE_URI => '_uri', // URL/URI type
-               SMWDataItem::TYPE_WIKIPAGE => '_wpg', // Page type
-               SMWDataItem::TYPE_NUMBER => '_num', // Number type
-               SMWDataItem::TYPE_TIME => '_dat', // Time type
-               SMWDataItem::TYPE_BOOLEAN => '_boo', // Boolean type
-               SMWDataItem::TYPE_CONTAINER => '_rec', // Value list type 
(replacing former nary properties)
-               SMWDataItem::TYPE_GEO => '_geo', // Geographical coordinates
-               SMWDataItem::TYPE_CONCEPT => '__con', // Special concept page 
type
-               SMWDataItem::TYPE_PROPERTY => '__pro', // Property type
-               // If either of the following two occurs, we want to see a PHP 
error:
-               //SMWDataItem::TYPE_NOTYPE => '',
-               //SMWDataItem::TYPE_ERROR => '',
-       );
 
        /**
         * Create a value from a type id. If no $value is given, an empty
@@ -98,13 +43,12 @@
         *
         * @return SMWDataValue
         */
-       static public function newTypeIdValue( $typeId, $valueString = false, 
$caption = false,
+       public static function newTypeIdValue( $typeId, $valueString = false, 
$caption = false,
                        $property = null, $contextPage = null ) {
 
-               self::initDatatypes();
-
-               if ( array_key_exists( $typeId, self::$mTypeClasses ) ) {
-                       $result = new self::$mTypeClasses[$typeId]( $typeId );
+               if ( DataTypeRegistry::getInstance()->hasDataTypeClassById( 
$typeId ) ) {
+                       $class  = 
DataTypeRegistry::getInstance()->getDataTypeClassById( $typeId );
+                       $result = new $class( $typeId );
                } else {
                        return new SMWErrorValue( $typeId,
                                wfMessage( 'smw_unknowntype', $typeId 
)->inContentLanguage()->text(),
@@ -135,11 +79,11 @@
         *
         * @return SMWDataValue
         */
-       static public function newDataItemValue( SMWDataItem $dataItem, 
SMWDIProperty $property = null, $caption = false ) {
+       public static function newDataItemValue( SMWDataItem $dataItem, 
DIProperty $property = null, $caption = false ) {
                if ( !is_null( $property ) ) {
                        $typeId = $property->findPropertyTypeID();
                } else {
-                       $typeId = 
self::$mDefaultDataItemTypeIds[$dataItem->getDiType()];
+                       $typeId = 
DataTypeRegistry::getInstance()->getDefaultDataItemTypeId( 
$dataItem->getDiType() );
                }
 
                $result = self::newTypeIdValue( $typeId, false, $caption, 
$property );
@@ -150,28 +94,6 @@
                }
 
                return $result;
-       }
-
-
-       /**
-        * Get the preferred data item ID for a given type. The ID defines the
-        * appropriate data item class for processing data of this type. See
-        * SMWDataItem for possible values.
-        *
-        * @note SMWDIContainer is a pseudo dataitem type that is used only in
-        * data input methods, but not for storing data. Types that work with
-        * SMWDIContainer use SMWDIWikiPage as their DI type. (Since SMW 1.8)
-        *
-        * @param $typeId string id string for the given type
-        * @return integer data item ID
-        */
-       static public function getDataItemId( $typeId ) {
-               self::initDatatypes();
-               if ( array_key_exists( $typeId, self::$mTypeDataItemIds ) ) {
-                       return self::$mTypeDataItemIds[$typeId];
-               } else {
-                       return SMWDataItem::TYPE_NOTYPE;
-               }
        }
 
        /**
@@ -186,7 +108,7 @@
         *
         * @return SMWDataValue
         */
-       static public function newPropertyObjectValue( SMWDIProperty $property, 
$valueString = false,
+       public static function newPropertyObjectValue( DIProperty $property, 
$valueString = false,
                        $caption = false, $contextPage = null ) {
 
                $typeId = $property->isInverse() ? '_wpg' : 
$property->findPropertyTypeID();
@@ -208,7 +130,7 @@
         * @return SMWDataValue
         */
        public static function newPropertyValue( $propertyName, $valueString,
-               $caption = false, SMWDIWikiPage $contextPage = null ) {
+               $caption = false, DIWikiPage $contextPage = null ) {
 
                Profiler::In( __METHOD__, true );
 
@@ -226,14 +148,14 @@
                        return $propertyDV;
                }
 
-               if ( $propertyDI instanceof SMWDIProperty && 
!$propertyDI->isInverse() ) {
+               if ( $propertyDI instanceof DIProperty && 
!$propertyDI->isInverse() ) {
                        $dataValue = self::newPropertyObjectValue(
                                $propertyDI,
                                $valueString,
                                $caption,
                                $contextPage
                        );
-               } else if ( $propertyDI instanceof SMWDIProperty && 
$propertyDI->isInverse() ) {
+               } else if ( $propertyDI instanceof DIProperty && 
$propertyDI->isInverse() ) {
                        $dataValue = new SMWErrorValue( 
$propertyDV->getPropertyTypeID(),
                                wfMessage( 'smw_noinvannot' 
)->inContentLanguage()->text(),
                                $valueString, $caption
@@ -250,197 +172,57 @@
        }
 
        /**
-        * Gather all available datatypes and label<=>id<=>datatype
-        * associations. This method is called before most methods of this
-        * factory.
+        * Deprecated since 1.9 and be removed in 1.10, use DataTypeRegistry 
instead
+        *
+        * @since  1.9
         */
-       static protected function initDatatypes() {
-               /**
-                * @var SMWLanguage $smwgContLang
-                */
-               global $smwgContLang;
-
-               if ( is_array( self::$mTypeLabels ) ) {
-                       return; // init happened before
-               }
-
-               self::$mTypeLabels = $smwgContLang->getDatatypeLabels();
-               self::$mTypeAliases = $smwgContLang->getDatatypeAliases();
-
-               // Setup built-in datatypes.
-               // NOTE: all ids must start with underscores, where two 
underscores indicate
-               // truly internal (non user-acessible types). All others should 
also get a
-               // translation in the language files, or they won't be 
available for users.
-               self::$mTypeClasses = array(
-                       '_txt'  => 'SMWStringValue', // Text type
-                       '_cod'  => 'SMWStringValue', // Code type
-                       '_str'  => 'SMWStringValue', // DEPRECATED Will vanish 
after SMW 1.9; use '_txt'
-                       '_ema'  => 'SMWURIValue', // Email type
-                       '_uri'  => 'SMWURIValue', // URL/URI type
-                       '_anu'  => 'SMWURIValue', // Annotation URI type
-                       '_tel'  => 'SMWURIValue', // Phone number (URI) type
-                       '_wpg'  => 'SMWWikiPageValue', // Page type
-                       '_wpp'  => 'SMWWikiPageValue', // Property page type 
TODO: make available to user space
-                       '_wpc'  => 'SMWWikiPageValue', // Category page type 
TODO: make available to user space
-                       '_wpf'  => 'SMWWikiPageValue', // Form page type for 
Semantic Forms
-                       '_num'  => 'SMWNumberValue', // Number type
-                       '_tem'  => 'SMWTemperatureValue', // Temperature type
-                       '_dat'  => 'SMWTimeValue', // Time type
-                       '_boo'  => 'SMWBoolValue', // Boolean type
-                       '_rec'  => 'SMWRecordValue', // Value list type 
(replacing former nary properties)
-                       '_qty'  => 'SMWQuantityValue', // Type for numbers with 
units of measurement
-                       // Special types are not avaialble directly for users 
(and have no local language name):
-                       '__typ' => 'SMWTypesValue', // Special type page type
-                       '__pls' => 'SMWPropertyListValue', // Special type list 
for decalring _rec properties
-                       '__con' => 'SMWConceptValue', // Special concept page 
type
-                       '__sps' => 'SMWStringValue', // Special string type
-                       '__spu' => 'SMWURIValue', // Special uri type
-                       '__sup' => 'SMWWikiPageValue', // Special subproperty 
type
-                       '__suc' => 'SMWWikiPageValue', // Special subcategory 
type
-                       '__spf' => 'SMWWikiPageValue', // Special Form page 
type for Semantic Forms
-                       '__sin' => 'SMWWikiPageValue', // Special instance of 
type
-                       '__red' => 'SMWWikiPageValue', // Special redirect type
-                       '__err' => 'SMWErrorValue', // Special error type
-                       '__imp' => 'SMWImportValue', // Special import 
vocabulary type
-                       '__pro' => 'SMWPropertyValue', // Property type 
(possibly predefined, no always based on a page)
-                       '__key' => 'SMWStringValue', // Sort key of a page
-               );
-
-               self::$mTypeDataItemIds = array(
-                       '_txt'  => SMWDataItem::TYPE_BLOB, // Text type
-                       '_cod'  => SMWDataItem::TYPE_BLOB, // Code type
-                       '_str'  => SMWDataItem::TYPE_BLOB, // DEPRECATED Will 
vanish after SMW 1.9; use '_txt'
-                       '_ema'  => SMWDataItem::TYPE_URI, // Email type
-                       '_uri'  => SMWDataItem::TYPE_URI, // URL/URI type
-                       '_anu'  => SMWDataItem::TYPE_URI, // Annotation URI type
-                       '_tel'  => SMWDataItem::TYPE_URI, // Phone number (URI) 
type
-                       '_wpg'  => SMWDataItem::TYPE_WIKIPAGE, // Page type
-                       '_wpp'  => SMWDataItem::TYPE_WIKIPAGE, // Property page 
type TODO: make available to user space
-                       '_wpc'  => SMWDataItem::TYPE_WIKIPAGE, // Category page 
type TODO: make available to user space
-                       '_wpf'  => SMWDataItem::TYPE_WIKIPAGE, // Form page 
type for Semantic Forms
-                       '_num'  => SMWDataItem::TYPE_NUMBER, // Number type
-                       '_tem'  => SMWDataItem::TYPE_NUMBER, // Temperature type
-                       '_dat'  => SMWDataItem::TYPE_TIME, // Time type
-                       '_boo'  => SMWDataItem::TYPE_BOOLEAN, // Boolean type
-                       '_rec'  => SMWDataItem::TYPE_WIKIPAGE, // Value list 
type (replacing former nary properties)
-                       '_geo'  => SMWDataItem::TYPE_GEO, // Geographical 
coordinates
-                       '_gpo'  => SMWDataItem::TYPE_BLOB, // Geographical 
polygon
-                       '_qty'  => SMWDataItem::TYPE_NUMBER, // Type for 
numbers with units of measurement
-                       // Special types are not avaialble directly for users 
(and have no local language name):
-                       '__typ' => SMWDataItem::TYPE_URI, // Special type page 
type
-                       '__pls' => SMWDataItem::TYPE_BLOB, // Special type list 
for decalring _rec properties
-                       '__con' => SMWDataItem::TYPE_CONCEPT, // Special 
concept page type
-                       '__sps' => SMWDataItem::TYPE_BLOB, // Special string 
type
-                       '__spu' => SMWDataItem::TYPE_URI, // Special uri type
-                       '__sup' => SMWDataItem::TYPE_WIKIPAGE, // Special 
subproperty type
-                       '__suc' => SMWDataItem::TYPE_WIKIPAGE, // Special 
subcategory type
-                       '__spf' => SMWDataItem::TYPE_WIKIPAGE, // Special Form 
page type for Semantic Forms
-                       '__sin' => SMWDataItem::TYPE_WIKIPAGE, // Special 
instance of type
-                       '__red' => SMWDataItem::TYPE_WIKIPAGE, // Special 
redirect type
-                       '__err' => SMWDataItem::TYPE_ERROR, // Special error 
type
-                       '__imp' => SMWDataItem::TYPE_BLOB, // Special import 
vocabulary type
-                       '__pro' => SMWDataItem::TYPE_PROPERTY, // Property type 
(possibly predefined, no always based on a page)
-                       '__key' => SMWDataItem::TYPE_BLOB, // Sort key of a page
-               );
-
-               wfRunHooks( 'smwInitDatatypes' );
+       public static function registerDatatype( $id, $className, $dataItemId, 
$label = false ) {
+               DataTypeRegistry::getInstance()->egisterDatatype( $id, 
$className, $dataItemId, $label );
        }
 
        /**
-        * A function for registering/overwriting datatypes for SMW. Should be
-        * called from within the hook 'smwInitDatatypes'.
+        * Deprecated since 1.9 and be removed in 1.10, use DataTypeRegistry 
instead
         *
-        * @param $id string type ID for which this datatype is registered
-        * @param $className string name of the according subclass of 
SMWDataValue
-        * @param $dataItemId integer ID of the data item class that this data 
value uses, see SMWDataItem
-        * @param $label mixed string label or false for types that cannot be 
accessed by users
+        * @since  1.9
         */
-       static public function registerDatatype( $id, $className, $dataItemId, 
$label = false ) {
-               self::$mTypeClasses[$id] = $className;
-               self::$mTypeDataItemIds[$id] = $dataItemId;
-
-               if ( $label != false ) {
-                       self::$mTypeLabels[$id] = $label;
-               }
+       public static function registerDatatypeAlias( $id, $label ) {
+               DataTypeRegistry::getInstance()->registerDatatypeAlias( $id, 
$label );
        }
 
        /**
-        * Add a new alias label to an existing datatype id. Note that every ID
-        * should have a primary label, either provided by SMW or registered 
with
-        * registerDatatype(). This function should be called from within the 
hook
-        * 'smwInitDatatypes'.
+        * Deprecated since 1.9 and be removed in 1.10, use DataTypeRegistry 
instead
         *
-        * @param string $id
-        * @param string $label
+        * @since  1.9
         */
-       static public function registerDatatypeAlias( $id, $label ) {
-               self::$mTypeAliases[$label] = $id;
+       public static  function findTypeID( $label, $useAlias = true ) {
+               return DataTypeRegistry::getInstance()->findTypeID( $label, 
$useAlias );
        }
 
        /**
-        * Look up the ID that identifies the datatype of the given label
-        * internally. This id is used for all internal operations. If the
-        * label does not bleong to a known type, the empty string is returned.
+        * Deprecated since 1.9 and be removed in 1.10, use DataTypeRegistry 
instead
         *
-        * This method may or may not take aliases into account, depeding on
-        * the parameter $useAlias.
-        *
-        * @param string $label
-        * @param boolean $useAlias
-        * @return string
+        * @since  1.9
         */
-       static public function findTypeID( $label, $useAlias = true ) {
-               self::initDatatypes();
-               $id = array_search( $label, self::$mTypeLabels );
-
-               if ( $id !== false ) {
-                       return $id;
-               } elseif ( ( $useAlias ) && ( array_key_exists( $label, 
self::$mTypeAliases ) ) ) {
-                       return self::$mTypeAliases[$label];
-               } else {
-                       return '';
-               }
+       public static function findTypeLabel( $id ) {
+               return DataTypeRegistry::getInstance()->findTypeLabel( $id );
        }
 
        /**
-        * Get the translated user label for a given internal ID. If the ID does
-        * not have a label associated with it in the current language, the
-        * empty string is returned. This is the case both for internal type ids
-        * and for invalid (unkown) type ids, so this method cannot be used to
-        * distinguish the two.
+        * Deprecated since 1.9 and be removed in 1.10, use DataTypeRegistry 
instead
         *
-        * @param string $id
+        * @since  1.9
         */
-       static public function findTypeLabel( $id ) {
-               self::initDatatypes();
-
-               if ( array_key_exists( $id, self::$mTypeLabels ) ) {
-                       return self::$mTypeLabels[$id];
-               } else { // internal type without translation to user space;
-                       // might also happen for historic types after an 
upgrade --
-                       // alas, we have no idea what the former label would 
have been
-                       return '';
-               }
+       public static function getKnownTypeLabels() {
+               return DataTypeRegistry::getInstance()->getKnownTypeLabels();
        }
 
        /**
-        * Return an array of all labels that a user might specify as the type 
of
-        * a property, and that are internal (i.e. not user defined). No labels 
are
-        * returned for internal types without user labels (e.g. the special 
types
-        * for some special properties), and for user defined types.
+        * Deprecated since 1.9 and be removed in 1.10, use DataTypeRegistry 
instead
         *
-        * @return array
+        * @since  1.9
         */
-       static public function getKnownTypeLabels() {
-               self::initDatatypes();
-               return self::$mTypeLabels;
+       public static function getDataItemId( $typeId ) {
+               return DataTypeRegistry::getInstance()->getDataItemId( $typeId 
);
        }
 
 }
-
-/**
- * SMWDataValueFactory
- *
- * @deprecated since SMW 1.9
- */
-class_alias( 'SMW\DataValueFactory', 'SMWDataValueFactory' );
diff --git a/tests/phpunit/includes/DataTypeRegistryTest.php 
b/tests/phpunit/includes/DataTypeRegistryTest.php
new file mode 100644
index 0000000..7d773c4
--- /dev/null
+++ b/tests/phpunit/includes/DataTypeRegistryTest.php
@@ -0,0 +1,107 @@
+<?php
+
+namespace SMW\Test;
+
+use SMW\DataTypeRegistry;
+use SMWDataItem;
+use SMWPropertyValue;
+
+use Title;
+
+/**
+ * Tests for the SMW\DataTypeRegistry class
+ *
+ * @since 1.9
+ *
+ * @file
+ *
+ * @licence GNU GPL v2+
+ * @author mwjames
+ */
+
+/**
+ * @covers \SMW\DataTypeRegistry
+ *
+ * @ingroup Test
+ *
+ * @group SMW
+ * @group SMWExtension
+ */
+class DataTypeRegistryTest extends SemanticMediaWikiTestCase {
+
+       /**
+        * Returns the name of the class to be tested
+        *
+        * @return string|false
+        */
+       public function getClass() {
+               return '\SMW\DataTypeRegistry';
+       }
+
+       /**
+        * @since 1.9
+        */
+       public function testGetInstance() {
+
+               $instance = DataTypeRegistry::getInstance();
+
+               // Default is handled by the method itself
+               $this->assertInstanceOf( $this->getClass(), $instance );
+
+               // Static instance
+               $this->assertTrue( DataTypeRegistry::getInstance() === 
$instance );
+
+               // Reset static instance
+               DataTypeRegistry::clear();
+               $this->assertTrue( DataTypeRegistry::getInstance() !== 
$instance );
+
+       }
+
+       /**
+        * @since 1.9
+        */
+       public function testRegisterDatatype() {
+
+               $this->assertNull(
+                       DataTypeRegistry::getInstance()->getDataTypeClassById( 
'_fom' ),
+                       'Asserts that before registration 
getDataTypeClassById() returns null'
+               );
+
+               DataTypeRegistry::getInstance()->registerDatatype( '_fom', 
'\SMW\FomValue', SMWDataItem::TYPE_GEO, 'FomValue' );
+
+               $this->assertEquals(
+                       '\SMW\FomValue',
+                       DataTypeRegistry::getInstance()->getDataTypeClassById( 
'_fom' ),
+                       'Asserts that getDataTypeClassById() returns the 
registered class'
+               );
+
+               $this->assertEquals(
+                       SMWDataItem::TYPE_GEO,
+                       DataTypeRegistry::getInstance()->getDataItemId( '_fom' 
),
+                       'Asserts that getDataItemId() returns the registered 
DataItem type'
+               );
+
+               $this->assertEquals(
+                       'FomValue',
+                       DataTypeRegistry::getInstance()->findTypeLabel( '_fom' 
),
+                       'Asserts that findTypeLabel() returns the registered 
label'
+               );
+
+       }
+
+       /**
+        * @since 1.9
+        */
+       public function testRegisterDatatypeAlias() {
+
+               DataTypeRegistry::getInstance()->registerDatatypeAlias( '_fom', 
'FomBar' );
+
+               $this->assertEquals(
+                       '_fom',
+                       DataTypeRegistry::getInstance()->findTypeID( 'FomBar' ),
+                       'Asserts that findTypeID returns the registered alias 
label'
+               );
+
+       }
+
+}
diff --git a/tests/phpunit/includes/DataValueFactoryTest.php 
b/tests/phpunit/includes/DataValueFactoryTest.php
index 80ac5ff..5160b5c 100644
--- a/tests/phpunit/includes/DataValueFactoryTest.php
+++ b/tests/phpunit/includes/DataValueFactoryTest.php
@@ -23,6 +23,7 @@
 
 /**
  * @covers \SMW\DataValueFactory
+ * @covers \SMW\DataTypeRegistry
  *
  * @ingroup Test
  *

-- 
To view, visit https://gerrit.wikimedia.org/r/89492
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I370262323c203cf480ac174acab6a1ebc366ac9e
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/SemanticMediaWiki
Gerrit-Branch: master
Gerrit-Owner: Mwjames <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to