PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/extensions/SemanticMediaWiki/includes/SMW_DataValueFactory.php

https://github.com/ChuguluGames/mediawiki-svn
PHP | 376 lines | 181 code | 31 blank | 164 comment | 20 complexity | c5c0dbfb86bcfaf3a99ec5cb8f693ab9 MD5 | raw file
  1. <?php
  2. /**
  3. * This file contains the SMWDataValueFactory class.
  4. *
  5. * @author Markus Krötzsch
  6. * @author Jeroen De Dauw
  7. *
  8. * @file
  9. * @ingroup SMWDataValues
  10. */
  11. /**
  12. * Factory class for creating SMWDataValue objects for supplied types or
  13. * properties and data values.
  14. *
  15. * The class has the main entry point newTypeIDValue(), which creates a new
  16. * datavalue object, possibly with preset user values, captions and
  17. * property names. To create suitable datavalues for a given property, the
  18. * method newPropertyObjectValue() can be used.
  19. *
  20. * Other than this, the class manages registration data for datatypes, and
  21. * provides various methods to access this information.
  22. *
  23. * @ingroup SMWDataValues
  24. */
  25. class SMWDataValueFactory {
  26. /**
  27. * Array of type labels indexed by type ids. Used for datatype resolution.
  28. *
  29. * @var array
  30. */
  31. static private $mTypeLabels;
  32. /**
  33. * Array of ids indexed by type aliases. Used for datatype resolution.
  34. *
  35. * @var array
  36. */
  37. static private $mTypeAliases;
  38. /**
  39. * Array of class names for creating new SMWDataValue, indexed by type id.
  40. *
  41. * @var array of string
  42. */
  43. static private $mTypeClasses;
  44. /**
  45. * Array of data item classes, indexed by type id.
  46. *
  47. * @var array of integer
  48. */
  49. static private $mTypeDataItemIds;
  50. /**
  51. * Array of default types to use for making datavalues for dataitems.
  52. *
  53. * @var array of string
  54. */
  55. static private $mDefaultDataItemTypeIds = array(
  56. SMWDataItem::TYPE_BLOB => '_txt', // Text type
  57. SMWDataItem::TYPE_STRING => '_str', // String type
  58. SMWDataItem::TYPE_URI => '_uri', // URL/URI type
  59. SMWDataItem::TYPE_WIKIPAGE => '_wpg', // Page type
  60. SMWDataItem::TYPE_NUMBER => '_num', // Number type
  61. SMWDataItem::TYPE_TIME => '_dat', // Time type
  62. SMWDataItem::TYPE_BOOLEAN => '_boo', // Boolean type
  63. SMWDataItem::TYPE_CONTAINER => '_rec', // Value list type (replacing former nary properties)
  64. SMWDataItem::TYPE_GEO => '_geo', // Geographical coordinates
  65. SMWDataItem::TYPE_CONCEPT => '__con', // Special concept page type
  66. SMWDataItem::TYPE_PROPERTY => '__pro', // Property type
  67. // If either of the following two occurs, we want to see a PHP error:
  68. //SMWDataItem::TYPE_NOTYPE => '',
  69. //SMWDataItem::TYPE_ERROR => '',
  70. );
  71. /**
  72. * Create a value from a type id. If no $value is given, an empty container
  73. * is created, the value of which can be set later on.
  74. *
  75. * @param $typeid string id string for the given type
  76. * @param $value mixed user value string, or false if unknown
  77. * @param $caption mixed user-defined caption, or false if none given
  78. * @param $property SMWDIProperty property object for which this value is made, or NULL
  79. *
  80. * @return SMWDataValue
  81. */
  82. static public function newTypeIdValue( $typeid, $value = false, $caption = false, $property = null ) {
  83. self::initDatatypes();
  84. if ( array_key_exists( $typeid, self::$mTypeClasses ) ) {
  85. $result = new self::$mTypeClasses[$typeid]( $typeid );
  86. } else {
  87. smwfLoadExtensionMessages( 'SemanticMediaWiki' );
  88. return new SMWErrorValue( $typeid, wfMsgForContent( 'smw_unknowntype', $typeid ), $value, $caption );
  89. }
  90. if ( $property !== null ) {
  91. $result->setProperty( $property );
  92. }
  93. if ( $value !== false ) {
  94. $result->setUserValue( $value, $caption );
  95. }
  96. return $result;
  97. }
  98. /**
  99. * Create a value for a data item.
  100. *
  101. * @param $dataItem SMWDataItem
  102. * @param $property mixed null or SMWDIProperty property object for which this value is made
  103. * @param $caption mixed user-defined caption, or false if none given
  104. *
  105. * @return SMWDataValue
  106. */
  107. static public function newDataItemValue( SMWDataItem $dataItem, $property, $caption = false ) {
  108. if ( $property !== null ) {
  109. $typeid = $property->findPropertyTypeID();
  110. } else {
  111. $typeid = self::$mDefaultDataItemTypeIds[$dataItem->getDiType()];
  112. }
  113. $result = self::newTypeIdValue( $typeid, false, $caption, $property );
  114. $result->setDataItem( $dataItem );
  115. if ( $caption !== false ) {
  116. $result->setCaption( $caption );
  117. }
  118. return $result;
  119. }
  120. /**
  121. * Get the preferred data item ID for a given type. The ID defines the
  122. * appropriate data item class for processing data of this type. See
  123. * SMWDataItem for possible values.
  124. *
  125. * @param $typeid string id string for the given type
  126. * @return integer data item ID
  127. */
  128. static public function getDataItemId( $typeid ) {
  129. self::initDatatypes();
  130. if ( array_key_exists( $typeid, self::$mTypeDataItemIds ) ) {
  131. return self::$mTypeDataItemIds[$typeid];
  132. } else {
  133. return SMWDataItem::TYPE_NOTYPE;
  134. }
  135. }
  136. /**
  137. * Create a value for the given property, provided as an SMWDIProperty
  138. * object. If no value is given, an empty container is created, the value
  139. * of which can be set later on.
  140. *
  141. * @param $property SMWDIProperty
  142. * @param $value mixed
  143. * @param $caption mixed
  144. *
  145. * @return SMWDataValue
  146. */
  147. static public function newPropertyObjectValue( SMWDIProperty $property, $value = false, $caption = false ) {
  148. if ( $property->isInverse() ) {
  149. return self::newTypeIdValue( '_wpg', $value, $caption, $property );
  150. } else {
  151. return self::newTypeIdValue( $property->findPropertyTypeID(), $value, $caption, $property );
  152. }
  153. }
  154. /**
  155. * Gather all available datatypes and label<=>id<=>datatype associations.
  156. * This method is called before most methods of this factory.
  157. */
  158. static protected function initDatatypes() {
  159. global $smwgContLang;
  160. if ( is_array( self::$mTypeLabels ) ) {
  161. return; // init happened before
  162. }
  163. self::$mTypeLabels = $smwgContLang->getDatatypeLabels();
  164. self::$mTypeAliases = $smwgContLang->getDatatypeAliases();
  165. // Setup built-in datatypes.
  166. // NOTE: all ids must start with underscores, where two underscores indicate
  167. // truly internal (non user-acessible types). All others should also get a
  168. // translation in the language files, or they won't be available for users.
  169. self::$mTypeClasses = array(
  170. '_txt' => 'SMWStringValue', // Text type
  171. '_cod' => 'SMWStringValue', // Code type
  172. '_str' => 'SMWStringValue', // String type
  173. '_ema' => 'SMWURIValue', // Email type
  174. '_uri' => 'SMWURIValue', // URL/URI type
  175. '_anu' => 'SMWURIValue', // Annotation URI type
  176. '_tel' => 'SMWURIValue', // Phone number (URI) type
  177. '_wpg' => 'SMWWikiPageValue', // Page type
  178. '_wpp' => 'SMWWikiPageValue', // Property page type TODO: make available to user space
  179. '_wpc' => 'SMWWikiPageValue', // Category page type TODO: make available to user space
  180. '_wpf' => 'SMWWikiPageValue', // Form page type for Semantic Forms
  181. '_num' => 'SMWNumberValue', // Number type
  182. '_tem' => 'SMWTemperatureValue', // Temperature type
  183. '_dat' => 'SMWTimeValue', // Time type
  184. '_boo' => 'SMWBoolValue', // Boolean type
  185. '_rec' => 'SMWRecordValue', // Value list type (replacing former nary properties)
  186. '_qty' => 'SMWQuantityValue', // Type for numbers with units of measurement
  187. // Special types are not avaialble directly for users (and have no local language name):
  188. '__typ' => 'SMWTypesValue', // Special type page type
  189. '__pls' => 'SMWPropertyListValue', // Special type list for decalring _rec properties
  190. '__con' => 'SMWConceptValue', // Special concept page type
  191. '__sps' => 'SMWStringValue', // Special string type
  192. '__spu' => 'SMWURIValue', // Special uri type
  193. '__sup' => 'SMWWikiPageValue', // Special subproperty type
  194. '__suc' => 'SMWWikiPageValue', // Special subcategory type
  195. '__spf' => 'SMWWikiPageValue', // Special Form page type for Semantic Forms
  196. '__sin' => 'SMWWikiPageValue', // Special instance of type
  197. '__red' => 'SMWWikiPageValue', // Special redirect type
  198. '__err' => 'SMWErrorValue', // Special error type
  199. '__imp' => 'SMWImportValue', // Special import vocabulary type
  200. '__pro' => 'SMWPropertyValue', // Property type (possibly predefined, no always based on a page)
  201. '__key' => 'SMWStringValue', // Sort key of a page
  202. );
  203. self::$mTypeDataItemIds = array(
  204. '_txt' => SMWDataItem::TYPE_BLOB, // Text type
  205. '_cod' => SMWDataItem::TYPE_BLOB, // Code type
  206. '_str' => SMWDataItem::TYPE_STRING, // String type
  207. '_ema' => SMWDataItem::TYPE_URI, // Email type
  208. '_uri' => SMWDataItem::TYPE_URI, // URL/URI type
  209. '_anu' => SMWDataItem::TYPE_URI, // Annotation URI type
  210. '_tel' => SMWDataItem::TYPE_URI, // Phone number (URI) type
  211. '_wpg' => SMWDataItem::TYPE_WIKIPAGE, // Page type
  212. '_wpp' => SMWDataItem::TYPE_WIKIPAGE, // Property page type TODO: make available to user space
  213. '_wpc' => SMWDataItem::TYPE_WIKIPAGE, // Category page type TODO: make available to user space
  214. '_wpf' => SMWDataItem::TYPE_WIKIPAGE, // Form page type for Semantic Forms
  215. '_num' => SMWDataItem::TYPE_NUMBER, // Number type
  216. '_tem' => SMWDataItem::TYPE_NUMBER, // Temperature type
  217. '_dat' => SMWDataItem::TYPE_TIME, // Time type
  218. '_boo' => SMWDataItem::TYPE_BOOLEAN, // Boolean type
  219. '_rec' => SMWDataItem::TYPE_CONTAINER, // Value list type (replacing former nary properties)
  220. '_geo' => SMWDataItem::TYPE_GEO, // Geographical coordinates
  221. '_qty' => SMWDataItem::TYPE_NUMBER, // Type for numbers with units of measurement
  222. // Special types are not avaialble directly for users (and have no local language name):
  223. '__typ' => SMWDataItem::TYPE_URI, // Special type page type
  224. '__pls' => SMWDataItem::TYPE_STRING, // Special type list for decalring _rec properties
  225. '__con' => SMWDataItem::TYPE_CONCEPT, // Special concept page type
  226. '__sps' => SMWDataItem::TYPE_STRING, // Special string type
  227. '__spu' => SMWDataItem::TYPE_URI, // Special uri type
  228. '__sup' => SMWDataItem::TYPE_WIKIPAGE, // Special subproperty type
  229. '__suc' => SMWDataItem::TYPE_WIKIPAGE, // Special subcategory type
  230. '__spf' => SMWDataItem::TYPE_WIKIPAGE, // Special Form page type for Semantic Forms
  231. '__sin' => SMWDataItem::TYPE_WIKIPAGE, // Special instance of type
  232. '__red' => SMWDataItem::TYPE_WIKIPAGE, // Special redirect type
  233. '__err' => SMWDataItem::TYPE_STRING, // Special error type
  234. '__imp' => SMWDataItem::TYPE_STRING, // Special import vocabulary type
  235. '__pro' => SMWDataItem::TYPE_PROPERTY, // Property type (possibly predefined, no always based on a page)
  236. '__key' => SMWDataItem::TYPE_STRING, // Sort key of a page
  237. );
  238. wfRunHooks( 'smwInitDatatypes' );
  239. }
  240. /**
  241. * A function for registering/overwriting datatypes for SMW. Should be
  242. * called from within the hook 'smwInitDatatypes'.
  243. *
  244. * @param $id string type ID for which this datatype is registered
  245. * @param $className string name of the according subclass of SMWDataValue
  246. * @param $dataItemId integer ID of the data item class that this data value uses, see SMWDataItem
  247. * @param $label mixed string label or false for types that cannot be accessed by users
  248. */
  249. static public function registerDatatype( $id, $className, $dataItemId, $label = false ) {
  250. self::$mTypeClasses[$id] = $className;
  251. self::$mTypeDataItemIds[$id] = $dataItemId;
  252. if ( $label != false ) {
  253. self::$mTypeLabels[$id] = $label;
  254. }
  255. }
  256. /**
  257. * Add a new alias label to an existing datatype id. Note that every ID
  258. * should have a primary label, either provided by SMW or registered with
  259. * registerDatatype(). This function should be called from within the hook
  260. * 'smwInitDatatypes'.
  261. *
  262. * @param string $id
  263. * @param string $label
  264. */
  265. static public function registerDatatypeAlias( $id, $label ) {
  266. self::$mTypeAliases[$label] = $id;
  267. }
  268. /**
  269. * Look up the ID that identifies the datatype of the given label
  270. * internally. This id is used for all internal operations. If the
  271. * label does not bleong to a known type, the empty string is returned.
  272. *
  273. * This method may or may not take aliases into account, depeding on
  274. * the parameter $useAlias.
  275. *
  276. * @param string $label
  277. * @param boolean $useAlias
  278. * @return string
  279. */
  280. static public function findTypeID( $label, $useAlias = true ) {
  281. self::initDatatypes();
  282. $id = array_search( $label, self::$mTypeLabels );
  283. if ( $id !== false ) {
  284. return $id;
  285. } elseif ( ( $useAlias ) && ( array_key_exists( $label, self::$mTypeAliases ) ) ) {
  286. return self::$mTypeAliases[$label];
  287. } else {
  288. return '';
  289. }
  290. }
  291. /**
  292. * Get the translated user label for a given internal ID. If the ID does
  293. * not have a label associated with it in the current language, the
  294. * empty string is returned. This is the case both for internal type ids
  295. * and for invalid (unkown) type ids, so this method cannot be used to
  296. * distinguish the two.
  297. *
  298. * @param string $id
  299. */
  300. static public function findTypeLabel( $id ) {
  301. self::initDatatypes();
  302. if ( array_key_exists( $id, self::$mTypeLabels ) ) {
  303. return self::$mTypeLabels[$id];
  304. } else { // internal type without translation to user space;
  305. // might also happen for historic types after an upgrade --
  306. // alas, we have no idea what the former label would have been
  307. return '';
  308. }
  309. }
  310. /**
  311. * Return an array of all labels that a user might specify as the type of
  312. * a property, and that are internal (i.e. not user defined). No labels are
  313. * returned for internal types without user labels (e.g. the special types
  314. * for some special properties), and for user defined types.
  315. *
  316. * @return array
  317. */
  318. static public function getKnownTypeLabels() {
  319. self::initDatatypes();
  320. return self::$mTypeLabels;
  321. }
  322. /**
  323. * Create an SMWDataValue object that can hold values for the type that the
  324. * given SMWTypesValue object specifies. If no $value is given, an empty
  325. * container is created, the value of which can be set later on.
  326. *
  327. * @param $typevalue SMWTypesValue Represents the type of the object
  328. * @param $value mixed user value string, or false if unknown
  329. * @param $caption mixed user-defined caption or false if none given
  330. * @param $property SMWDIProperty property object for which this value was made, or null
  331. *
  332. * @deprecated Like all datavalues, SMWTypesValue objects should only be
  333. * used for parsing type inputs, or for producing formatted outputs.
  334. * Internal functions like datavalue creation should avoid them.
  335. * Use newTypeIdValue() instead. This function will vanish before SMW 1.7.
  336. */
  337. static public function newTypeObjectValue( SMWTypesValue $typeValue, $value = false, $caption = false, $property = null ) {
  338. if ( !$typeValue->isValid() ) { // just return the error, pass it through
  339. $result = self::newTypeIDValue( '__err' );
  340. $result->addError( $typeValue->getErrors() );
  341. return $result;
  342. }
  343. return self::newTypeIDValue( $typeValue->getDBkey(), $value, $caption, $property );
  344. }
  345. }