/extensions/SemanticMediaWiki/includes/datavalues/SMW_DV_Record.php

https://github.com/ChuguluGames/mediawiki-svn · PHP · 298 lines · 188 code · 41 blank · 69 comment · 53 complexity · 8523b38b07fe53a2e10a980425247c0d MD5 · raw file

  1. <?php
  2. /**
  3. * @file
  4. * @ingroup SMWDataValues
  5. */
  6. /**
  7. * SMWDataValue implements the handling of short lists of values,
  8. * where the order governs the type of each entry.
  9. *
  10. * @todo Enforce limitation of maximal number of values.
  11. * @todo Complete internationalisation.
  12. *
  13. * @author Markus Krötzsch
  14. * @ingroup SMWDataValues
  15. */
  16. class SMWRecordValue extends SMWDataValue {
  17. /// cache for properties for the fields of this data value
  18. protected $m_diProperties = null;
  19. protected function parseUserValue( $value ) {
  20. $this->parseUserValueOrQuery( $value, false );
  21. }
  22. protected function parseUserValueOrQuery( $value, $queryMode ) {
  23. if ( $value == '' ) {
  24. smwfLoadExtensionMessages( 'SemanticMediaWiki' );
  25. $this->addError( wfMsg( 'smw_novalues' ) );
  26. if ( $queryMode ) {
  27. return new SMWThingDescription();
  28. } else {
  29. return;
  30. }
  31. }
  32. if ( $queryMode ) {
  33. $subdescriptions = array();
  34. } else {
  35. $semanticData = new SMWContainerSemanticData();
  36. }
  37. $values = preg_split( '/[\s]*;[\s]*/u', trim( $value ) );
  38. $valueIndex = 0; // index in value array
  39. $propertyIndex = 0; // index in property list
  40. $empty = true;
  41. foreach ( $this->getPropertyDataItems() as $diProperty ) {
  42. if ( !array_key_exists( $valueIndex, $values ) ) {
  43. break; // stop if there are no values left
  44. }
  45. if ( $queryMode ) { // special handling for supporting query parsing
  46. $comparator = SMW_CMP_EQ;
  47. SMWDataValue::prepareValue( $values[$valueIndex], $comparator );
  48. }
  49. // generating the DVs:
  50. if ( ( $values[$valueIndex] == '' ) || ( $values[$valueIndex] == '?' ) ) { // explicit omission
  51. $valueIndex++;
  52. } else {
  53. $dataValue = SMWDataValueFactory::newPropertyObjectValue( $diProperty, $values[$valueIndex] );
  54. if ( $dataValue->isValid() ) { // valid DV: keep
  55. if ( $queryMode ) {
  56. $subdescriptions[] = new SMWSomeProperty( $diProperty, new SMWValueDescription( $dataValue->getDataItem(), $comparator ) );
  57. } else {
  58. $semanticData->addPropertyObjectValue( $diProperty, $dataValue->getDataItem() );
  59. }
  60. $valueIndex++;
  61. $empty = false;
  62. } elseif ( ( count( $values ) - $valueIndex ) == ( count( $this->m_diProperties ) - $propertyIndex ) ) {
  63. // too many errors: keep this one to have enough slots left
  64. if ( !$queryMode ) {
  65. $semanticData->addPropertyObjectValue( $diProperty, $dataValue->getDataItem() );
  66. }
  67. $this->addError( $dataValue->getErrors() );
  68. $valueIndex++;
  69. }
  70. }
  71. ++$propertyIndex;
  72. }
  73. if ( $empty ) {
  74. smwfLoadExtensionMessages( 'SemanticMediaWiki' );
  75. $this->addError( wfMsg( 'smw_novalues' ) );
  76. }
  77. if ( $queryMode ) {
  78. switch ( count( $subdescriptions ) ) {
  79. case 0: return new SMWThingDescription();
  80. case 1: return reset( $subdescriptions );
  81. default: return new SMWConjunction( $subdescriptions );
  82. }
  83. } else {
  84. $this->m_dataitem = new SMWDIContainer( $semanticData, $this->m_typeid );
  85. }
  86. }
  87. /**
  88. * @see SMWDataValue::loadDataItem()
  89. * @param $dataitem SMWDataItem
  90. * @return boolean
  91. */
  92. protected function loadDataItem( SMWDataItem $dataItem ) {
  93. if ( $dataItem->getDIType() == SMWDataItem::TYPE_CONTAINER ) {
  94. $this->m_dataitem = $dataItem;
  95. return true;
  96. } else {
  97. return false;
  98. }
  99. }
  100. /**
  101. * Overwrite SMWDataValue::getQueryDescription() to be able to process
  102. * comparators between all values.
  103. */
  104. public function getQueryDescription( $value ) {
  105. return $this->parseUserValueOrQuery( $value, true );
  106. }
  107. public function getShortWikiText( $linked = null ) {
  108. if ( $this->m_caption !== false ) {
  109. return $this->m_caption;
  110. }
  111. return $this->makeOutputText( 0, $linked );
  112. }
  113. public function getShortHTMLText( $linker = null ) {
  114. if ( $this->m_caption !== false ) {
  115. return $this->m_caption;
  116. }
  117. return $this->makeOutputText( 1, $linker );
  118. }
  119. public function getLongWikiText( $linked = null ) {
  120. return $this->makeOutputText( 2, $linked );
  121. }
  122. public function getLongHTMLText( $linker = null ) {
  123. return $this->makeOutputText( 3, $linker );
  124. }
  125. public function getWikiValue() {
  126. return $this->makeOutputText( 4 );
  127. }
  128. /// @todo Allowed values for multi-valued properties are not supported yet.
  129. protected function checkAllowedValues() { }
  130. /**
  131. * Make sure that the content is reset in this case.
  132. * @todo This is not a full reset yet (the case that property is changed after a value
  133. * was set does not occur in the normal flow of things, hence this has low priority).
  134. */
  135. public function setProperty( SMWDIProperty $property ) {
  136. parent::setProperty( $property );
  137. $this->m_diProperties = null;
  138. }
  139. ////// Additional API for value lists
  140. /**
  141. * @deprecated as of 1.6, use getDataItems instead
  142. *
  143. * @return array of SMWDataItem
  144. */
  145. public function getDVs() {
  146. return $this->getDataItems();
  147. }
  148. /**
  149. * Create a list (array with numeric keys) containing the datavalue
  150. * objects that this SMWRecordValue object holds. Values that are not
  151. * present are set to null. Note that the first index in the array is
  152. * 0, not 1.
  153. *
  154. * @since 1.6
  155. *
  156. * @return array of SMWDataItem
  157. */
  158. public function getDataItems() {
  159. if ( $this->isValid() ) {
  160. $result = array();
  161. $index = 0;
  162. foreach ( $this->getPropertyDataItems() as $diProperty ) {
  163. $values = $this->getDataItem()->getSemanticData()->getPropertyValues( $diProperty );
  164. if ( count( $values ) > 0 ) {
  165. $result[$index] = reset( $values );
  166. } else {
  167. $result[$index] = null;
  168. }
  169. $index += 1;
  170. }
  171. return $result;
  172. } else {
  173. return array();
  174. }
  175. }
  176. /**
  177. * Return the array (list) of properties that the individual entries of
  178. * this datatype consist of.
  179. *
  180. * @since 1.6
  181. *
  182. * @todo I18N for error message.
  183. *
  184. * @return array of SMWDIProperty
  185. */
  186. public function getPropertyDataItems() {
  187. if ( $this->m_diProperties === null ) {
  188. $this->m_diProperties = self::findPropertyDataItems( $this->m_property );
  189. if ( count( $this->m_diProperties ) == 0 ) { //TODO internalionalize
  190. $this->addError( 'The list of properties to be used for the data fields has not been specified properly.' );
  191. }
  192. }
  193. return $this->m_diProperties;
  194. }
  195. /**
  196. * Return the array (list) of properties that the individual entries of
  197. * this datatype consist of.
  198. *
  199. * @since 1.6
  200. *
  201. * @param $diProperty mixed null or SMWDIProperty object for which to retrieve the types
  202. *
  203. * @return array of SMWDIProperty
  204. */
  205. public static function findPropertyDataItems( $diProperty ) {
  206. if ( !is_null( $diProperty ) ) {
  207. $propertyDiWikiPage = $diProperty->getDiWikiPage();
  208. if ( !is_null( $propertyDiWikiPage ) ) {
  209. $listDiProperty = new SMWDIProperty( '_LIST' );
  210. $dataItems = smwfGetStore()->getPropertyValues( $propertyDiWikiPage, $listDiProperty );
  211. if ( count( $dataItems ) == 1 ) {
  212. $propertyListValue = new SMWPropertyListValue( '__pls' );
  213. $propertyListValue->setDataItem( reset( $dataItems ) );
  214. if ( $propertyListValue->isValid() ) {
  215. return $propertyListValue->getPropertyDataItems();
  216. }
  217. }
  218. }
  219. }
  220. return array();
  221. }
  222. ////// Internal helper functions
  223. protected function makeOutputText( $type = 0, $linker = null ) {
  224. if ( !$this->isValid() ) {
  225. return ( ( $type == 0 ) || ( $type == 1 ) ) ? '' : $this->getErrorText();
  226. }
  227. $result = '';
  228. $i = 0;
  229. foreach ( $this->getPropertyDataItems() as $propertyDataItem ) {
  230. if ( $i == 1 ) {
  231. $result .= ( $type == 4 ) ? '; ' : ' (';
  232. } elseif ( $i > 1 ) {
  233. $result .= ( $type == 4 ) ? '; ' : ', ';
  234. }
  235. ++$i;
  236. $propertyValues = $this->m_dataitem->getSemanticData()->getPropertyValues( $propertyDataItem ); // combining this with next line violates PHP strict standards
  237. $dataItem = reset( $propertyValues );
  238. if ( $dataItem !== false ) {
  239. $dataValue = SMWDataValueFactory::newDataItemValue( $dataItem, $propertyDataItem );
  240. $result .= $this->makeValueOutputText( $type, $dataValue, $linker );
  241. } else {
  242. $result .= '?';
  243. }
  244. }
  245. if ( ( $i > 1 ) && ( $type != 4 ) ) $result .= ')';
  246. return $result;
  247. }
  248. protected function makeValueOutputText( $type, $dataValue, $linker ) {
  249. switch ( $type ) {
  250. case 0: return $dataValue->getShortWikiText( $linker );
  251. case 1: return $dataValue->getShortHTMLText( $linker );
  252. case 2: return $dataValue->getShortWikiText( $linker );
  253. case 3: return $dataValue->getShortHTMLText( $linker );
  254. case 4: return $dataValue->getWikiValue();
  255. }
  256. }
  257. }