ok, i think i implemented this. 

the example is a bug 'severity' enumeration. 

the attribute page is:

[[has type::Type:Severity]]

the type pages is:
[[Enum mapping:=Blocker=7]]
[[Enum mapping:=Critical=6]]
[[Enum mapping:=Major=5]]
[[Enum mapping:=Normal=4]]
[[Enum mapping:=Minor=3]]
[[Enum mapping:=Trivial=2]]
[[Enum mapping:=Enhancement=1]]


then, i can do stuff like <ask>[[severity:=>Normal]]</ask>

here is the patch

diff -u -r /tmp/SemanticMediaWiki/includes/SMW_DT_Integer.php 
SemanticMediaWiki/includes/SMW_DT_Integer.php
--- /tmp/SemanticMediaWiki/includes/SMW_DT_Integer.php  2007-01-07 
10:39:35.000000000 +0200
+++ SemanticMediaWiki/includes/SMW_DT_Integer.php       2007-01-07 
14:21:07.000000000 +0200
@@ -60,4 +60,76 @@
        }
 }
 
-?>
\ No newline at end of file
+/**
+ * Class for managing integer types. Parses whole number
+ * strings and generates appropriate error messages on
+ * failure.
+ */
+class SMWEnumTypeHandler extends SMWIntegerTypeHandler {
+       protected $typeid;
+
+       protected $mappings = array();
+
+       /**
+         * Constructor. Since the linear type is polymorphic, a 
+         * typeid is needed to be able to retrieve the right type for
+         * values stored in the database (where the typeid is used).
+         */
+        function SMWEnumTypeHandler($typeid, $mappings = NULL) {
+                $this->typeid = str_replace(' ', '_', $typeid);
+                if ($mappings !== NULL) {
+                        $this->parseMappings($mappings);
+                }
+        }
+
+       function parseMappings($mappings) {
+               foreach ($mappings as $mapping) {
+                       list($name, $value) = explode("=", $mapping);
+                       $this->mappings[$name] = $value;
+               }
+       }
+
+       function getID() {
+               return $this->typeid;
+       }
+
+       function getXSDType() {
+               return 'http://www.w3.org/2001/XMLSchema#' . $this->typeid;
+       }
+
+       function getUnits() { //no units for enum
+               return array('STDUNIT'=>false, 'ALLUNITS'=>array());
+       }
+
+       function processValue($v,&$datavalue) {
+               if (array_key_exists($v, $this->mappings)) {
+                       $datavalue->setProcessedValues($v, $this->mappings[$v], 
$this->mappings[$v]);
+                       $datavalue->setPrintoutString($v);
+                       $datavalue->addQuicksearchLink();
+                       $datavalue->addServiceLinks($v);
+               } else {
+                       $datavalue->setError(wfMsgForContent($v . " is not a 
valid value for " . $this->getID()));
+               }
+               return;
+       }
+
+       /**
+        * This method parses the value in the XSD form that was
+        * generated by parsing some user input. It is needed since
+        * the XSD form must be compatible to XML, and thus does not
+        * respect the internationalization settings. E.g. the German
+        * input value "1,234" is translated into XSD "1.234" which,
+        * if reparsed as a user input would be misinterpreted as 1234.
+        *
+        * @public
+        */
+       function processXSDValue($value,$unit,&$datavalue) {
+               return $this->processValue($value . $unit, $datavalue);
+       }
+
+       function isNumeric() {
+               return TRUE;
+       }
+}
+
+?>
diff -u -r /tmp/SemanticMediaWiki/includes/SMW_Datatype.php 
SemanticMediaWiki/includes/SMW_Datatype.php
--- /tmp/SemanticMediaWiki/includes/SMW_Datatype.php    2007-01-07 
10:39:35.000000000 +0200
+++ SemanticMediaWiki/includes/SMW_Datatype.php 2007-01-07 14:16:26.000000000 
+0200
@@ -23,6 +23,7 @@
  *         Better to only load datatype PHP files as needed!?
  */
 require_once('SMW_DT_Float.php');
+require_once('SMW_DT_Integer.php');
 
 /**
  * Static class for registerig and retrieving typehandlers.
@@ -129,6 +130,8 @@
                                return new SMWStringTypeHandler();
                        case SMW_SP_CONVERSION_FACTOR:
                                return new SMWStringTypeHandler();
+                       case SMW_SP_ENUM_MAP:
+                                return new SMWStringTypeHandler();
                        default:
                                global $smwgContLang;
                                $specprops = 
$smwgContLang->getSpecialPropertiesArray();
@@ -141,10 +144,10 @@
         * (i.e. a localized type name), or an error type handler if the label
         * is not associated with some handler. The label is usually the article
         * name of the type, without the namepsace prefix (Type:). The optional
-        * parameter $findConversions can be used to prevent searching for 
custom
+        * parameter $findCustom can be used to prevent searching for custom
         * datatypes in cases where no built-in datatype is found.
         */
-       static function getTypeHandlerByLabel($typelabel, 
$findConversions=true) {
+       static function getTypeHandlerByLabel($typelabel, $findCustom=true) {
                if 
(array_key_exists($typelabel,SMWTypeHandlerFactory::$typeHandlersByLabel)) {
                        $th = 
SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel];
                        if (is_array($th)) { //instantiate the handler first
@@ -159,13 +162,21 @@
                        return 
SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel];
                }
                // Maybe a custom type? Try to find conversion factors:
-               if (!$findConversions) return NULL;
+               if (!$findCustom) return NULL;
                $conversionFactors = 
SMWTypeHandlerFactory::getConversionFactors($typelabel);
                if (count($conversionFactors) !== 0) {
                        $instance = new SMWLinearTypeHandler('Type:' . 
$typelabel, $conversionFactors); // no localisation needed -- "Type:" is just a 
disamb. string in the DB
                        SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel] 
= $instance;
                        return 
SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel];
                }
+
+               $enumMappings = 
SMWTypeHandlerFactory::getEnumMappings($typelabel);
+                if (count($enumMappings) !== 0) {
+                        $instance = new SMWEnumTypeHandler('Type:' . 
$typelabel, $enumMappings); // no localisation needed -- "Type:" is just a 
disamb. string in the DB
+                        
SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel] = $instance;
+                        return 
SMWTypeHandlerFactory::$typeHandlersByLabel[$typelabel];
+                }
+
                return new 
SMWErrorTypeHandler(wfMsgForContent('smw_unknowntype',$typelabel));
        }
 
@@ -253,6 +264,32 @@
                return $result;
        }
 
+        /**
+         * This method retrieves the enumeration mappings if any, for a 
+         * given type as an array of strings. It gets them from a special 
+         * property, e.g. if Attribute:Version HasType Type:Version, then
+         * Type:Version page has the enumeration mapping that we have to 
+         * pass to an SMWMappingTypeHandler instance.
+         *
+         * @return (possibly empty) array of enumeration mapping, each a string
+         * @param $type should be in text form without preceding namespace.
+         */
+        static function &getEnumMappings($type) {
+                global $wgContLang;
+
+                $result = array();
+                $ttitle = 
Title::newFromText($wgContLang->getNsText(SMW_NS_TYPE) . ':' . $type);
+                if ( ($ttitle !== NULL) && ($ttitle->exists()) ) {
+                        $tprops = &smwfGetSpecialProperties($ttitle, 
SMW_SP_ENUM_MAP, NULL); 
+                        foreach ($tprops as $uprops) {
+                                // uprops[2] has the value_string we want, 
append to array.
+                                $result[] = $uprops[2];
+                        }
+                }
+                return $result;
+        }
+
+
        /**
         * This method retrieves additional service links, if any, for a 
         * given type as an array of id strings. The ids are the back part
diff -u -r /tmp/SemanticMediaWiki/includes/SMW_Settings.php 
SemanticMediaWiki/includes/SMW_Settings.php
--- /tmp/SemanticMediaWiki/includes/SMW_Settings.php    2007-01-07 
10:39:35.000000000 +0200
+++ SemanticMediaWiki/includes/SMW_Settings.php 2007-01-07 12:55:04.000000000 
+0200
@@ -16,6 +16,7 @@
 define('SMW_SP_EXT_SECTION',11);
 define('SMW_SP_CONVERSION_FACTOR', 12);
 define('SMW_SP_SERVICE_LINK', 13);
+define('SMW_SP_ENUM_MAP', 100);
 
 // constants for displaying the factbox
 define('SMW_FACTBOX_HIDDEN', 1);
diff -u -r /tmp/SemanticMediaWiki/languages/SMW_LanguageEn.php 
SemanticMediaWiki/languages/SMW_LanguageEn.php
--- /tmp/SemanticMediaWiki/languages/SMW_LanguageEn.php 2007-01-07 
10:39:35.000000000 +0200
+++ SemanticMediaWiki/languages/SMW_LanguageEn.php      2007-01-07 
12:56:01.000000000 +0200
@@ -161,7 +161,8 @@
        SMW_SP_DISPLAY_UNIT => 'Display unit',
        SMW_SP_IMPORTED_FROM => 'Imported from',
        SMW_SP_CONVERSION_FACTOR => 'Corresponds to',
-       SMW_SP_SERVICE_LINK => 'Provides service'
+       SMW_SP_SERVICE_LINK => 'Provides service',
+       SMW_SP_ENUM_MAP => 'Enum mapping'
 );


S Page wrote:
> Ittay Dror wrote:
> 
>  > can i create an attribute whose type is some enumeration?
> 
> Not yet, but you join the list of people asking for this feature.
> 
> I should be coding better date/time handling :-)
> but this is pretty straightforward; I've got an implementation working 
> locally and should be able to check it into SVN tomorrow if no one objects.
> 
>  > the point is to have an attribute that accepts string values, but
>  > still be able to create order, and use comparisons in queries.
>  >
>  > my use case is a 'product_version' attribute. I'd like for different
>  > components to state since what product version they exist ('since
>  > version 1.2'). i want then to be able to list all components for a
>  > given version (something like [[product_version:=<1.3]]).
> 
> The inline query code would have to detect queries on the enumerated 
> datatype, look up the value_num for 1.3, and query on that.  I don't 
> have that part working.
> 
>  > version names can be anything (e.g. 'xp'). so i want to be able to
>  > map them in the attribute page (or type of). then i'd assign to 1.1
>  > the value of 1, to 1.2 the value of 2, to 'xp' the value of 3, etc.
> 
> In my "keep it simple" approach, the [[Attribute:Product version]] page 
> would have the special property
>    [[possible values:=3.0,3.1,98,98SE,ME,XP,Vista]]
> and each comma-separated value gets a numeric offset that you wouldn't 
> be able to control (or see).
> 
>  > when new versions come (incl. minor versions), i'll update the page,
>  > inserting the version and its sequence number (maybe bumping others)
> 
> In my "keep it simple" approach, if you inserted a new value within 
> possible values, you'd have to re-edit all pages with the attribute to 
> update the offsets.  If you really want an advanced enum type that lets 
> you control the numeric value of each string, how would you specify this 
> in wiki text?
> 
> In another message, Ittay Dror wrote:
>  > can anyone please give pointers (or example code) how to
>  > implement as custom type (php)?
> My PHP code for SMWEnumeratedTypeHandler is a combination of 
> SMWStringTypeHandler and SMWBooleanTypeHandler, with handling of the 
> special property "possible values" similar to "display units".  Nothing 
> innovative ;-)
> 
> Notes
> -----
> I don't think there's any way to represent an enumerated type in RDF 
> export beyond the string XSD type.
> 
> Although strings are the obvious case for enumeration, [[possible 
> values]] could also be applied to other attribute datatypes, and even to 
> relations.  But no one's asked for that yet.
> 
> The [[possible values]] special property will really run into the 255 
> character limit for string values.  But if you split the enumeration 
> across two [[possible value]] attributes, I don't think order is 
> guaranteed between them.
> 
> -- 
> =S
> 


-- 
===================================
Ittay Dror, 
Chief architect, 
R&D, Qlusters Inc.
[EMAIL PROTECTED]
+972-3-6081994 Fax: +972-3-6081841

www.openqrm.org - Data Center Provisioning

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Semediawiki-user mailing list
Semediawiki-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/semediawiki-user

Reply via email to