oops, didn't manage the conversions right.

here's the fixed SMWEnumTypeHandler:
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($enum,&$datavalue) {
                if (array_key_exists($enum, $this->mappings)) {
                        $this->setValue($enum, $this->mappings[$enum], 
$datavalue);
                } else {
                        $datavalue->setError(wfMsgForContent($enum . " is not a 
valid enumeration for " . $this->getID()));
                }
                return;
        }

        function setValue($enum, $value, &$datavalue) {
                $datavalue->setProcessedValues($enum, $value, $value);
                $datavalue->setPrintoutString($enum);
                $datavalue->addQuicksearchLink();
                $datavalue->addServiceLinks($enum);

        }

        /**
         * 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) {
                $enum = array_search($value, $this->mappings);
                if ($enum) {
                        $this->setValue($enum, $value, $datavalue);
                } else {
                        $datavalue->setError(wfMsgForContent($value . " is not 
a valid enum value for " . $this->getID()));
                }
        }

        function isNumeric() {
                return TRUE;
        }
}


Ittay Dror wrote:
> 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