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