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