r88196 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r88195‎ | r88196 | r88197 >
Date:17:01, 15 May 2011
Author:mkroetzsch
Status:deferred
Tags:
Comment:
restored basic Type:Record functionality for the SQL store
Modified paths:
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_CompatibilityHelpers.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_DataValue.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_DataValueFactory.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_Factbox.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_SemanticData.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/dataitems/SMW_DI_Container.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/datavalues/SMW_DV_Container.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/datavalues/SMW_DV_Record.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/datavalues/SMW_DV_TypeList.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SQLStore2.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SqlStubSemanticData.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/storage/SMW_Store.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/specials/SearchTriple/SMW_SpecialBrowse.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticMediaWiki/specials/SearchTriple/SMW_SpecialBrowse.php
@@ -153,7 +153,7 @@
154154 // if there are more incoming values than a certain treshold, display a link to the rest instead
155155 $body .= '<a href="' . $skin->makeSpecialUrl( 'SearchByProperty', 'property=' . urlencode( $dvProperty->getWikiValue() ) . '&value=' . urlencode( $this->subject->getWikiValue() ) ) . '">' . wfMsg( "smw_browse_more" ) . "</a>\n";
156156 } else {
157 - $dv = SMWDataValueFactory::newDataItemValue( $di );
 157+ $dv = SMWDataValueFactory::newDataItemValue( $di, false, $diProperty );
158158 $body .= "<span class=\"smwb-" . $inv . "value\">" .
159159 $this->displayValue( $dvProperty, $dv, $incoming ) . "</span>";
160160 }
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_DataValue.php
@@ -63,7 +63,7 @@
6464
6565 /**
6666 * The text label of the respective property or false if none given.
67 - * @var unknown_type
 67+ * @var SMWDIProperty
6868 */
6969 protected $m_property = null;
7070
@@ -74,12 +74,6 @@
7575 protected $m_caption;
7676
7777 /**
78 - * True if a value was set.
79 - * @var boolean
80 - */
81 - private $m_isset;
82 -
83 - /**
8478 * The type id for this value object.
8579 * @var string
8680 */
@@ -256,7 +250,10 @@
257251 if ( $this->mHasServiceLinks ) {
258252 return;
259253 }
260 - if ( ( $this->m_property === null ) || ( $this->m_property->getWikiPageValue() === null ) ) {
 254+ if ( $this->m_property !== null ) {
 255+ $propertyDiWikiPage = $this->m_property->getDiWikiPage();
 256+ }
 257+ if ( ( $this->m_property === null ) || ( $propertyDiWikiPage === null ) ) {
261258 return; // no property known
262259 }
263260
@@ -267,11 +264,12 @@
268265 }
269266
270267 array_unshift( $args, '' ); // add a 0 element as placeholder
271 - $servicelinks = smwfGetStore()->getPropertyValues( $this->m_property->getWikiPageValue(), new SMWDIProperty( '_SERV' ) );
 268+ $servicelinks = smwfGetStore()->getPropertyValues( $propertyDiWikiPage, new SMWDIProperty( '_SERV' ) );
272269
273 - foreach ( $servicelinks as $dv ) {
 270+ foreach ( $servicelinks as $dataItem ) {
274271 smwfLoadExtensionMessages( 'SemanticMediaWiki' );
275 -
 272+ $dv = SMWDataValueFactory::newDataItemValue( $dataItem );
 273+
276274 $args[0] = 'smw_service_' . str_replace( ' ', '_', $dv->getWikiValue() ); // messages distinguish ' ' from '_'
277275 $text = call_user_func_array( 'wfMsgForContent', $args );
278276 $links = preg_split( "/[\n][\s]?/u", $text );
@@ -681,10 +679,11 @@
682680 * text, but no more. Result might have no entries but is always an array.
683681 */
684682 public function getInfolinks() {
685 - if ( $this->isValid() && ( $this->m_property !== null ) && ( $this->m_property->getWikiPageValue() !== null ) ) {
 683+ if ( $this->isValid() && ( $this->m_property !== null ) ) {
686684 if ( !$this->mHasSearchLink ) { // add default search link
 685+ $propertyDataValue = SMWDataValueFactory::newDataItemValue( $this->m_property );
687686 $this->mHasSearchLink = true;
688 - $this->m_infolinks[] = SMWInfolink::newPropertySearchLink( '+', $this->m_property->getWikiValue(), $this->getWikiValue() );
 687+ $this->m_infolinks[] = SMWInfolink::newPropertySearchLink( '+', $propertyDataValue->getWikiValue(), $this->getWikiValue() );
689688 }
690689
691690 if ( !$this->mHasServiceLinks ) { // add further service links
@@ -795,12 +794,16 @@
796795 * Creates an error if the value is illegal.
797796 */
798797 protected function checkAllowedValues() {
799 - if ( ( $this->m_property === null ) || ( $this->m_property->getDiWikiPage() === null ) || ( !isset( $this->m_dataitem ) ) ) {
 798+ if ( $this->m_property !== null ) {
 799+ $propertyDiWikiPage = $this->m_property->getDiWikiPage();
 800+ }
 801+
 802+ if ( ( $this->m_property === null ) || ( $propertyDiWikiPage === null ) || ( !isset( $this->m_dataitem ) ) ) {
800803 return; // no property known, or no data to check
801804 }
802805
803806 $allowedvalues = smwfGetStore()->getPropertyValues(
804 - $this->m_property->getDiWikiPage(),
 807+ $propertyDiWikiPage,
805808 new SMWDIProperty( '_PVAL' )
806809 );
807810
@@ -835,19 +838,5 @@
836839 );
837840 }
838841 }
839 -
840 - /**
841 - * Returns if the data value holds info about a main object (page)
842 - * or not (property). This allows query printers to distinguise
843 - * the main object from properties of type page (count does not
844 - * suffice as the main object can be omitted using mainlabel=-)
845 - *
846 - * @since 1.5.6
847 - *
848 - * @return boolean
849 - */
850 - public function isMainObject() {
851 - return $this->m_property == null;
852 - }
853842
854843 }
\ No newline at end of file
Index: trunk/extensions/SemanticMediaWiki/includes/datavalues/SMW_DV_TypeList.php
@@ -16,7 +16,7 @@
1717
1818 /**
1919 * List of type data value objects corresponding to the stored data.
20 - * @var array
 20+ * @var array of SMWTypesValue
2121 */
2222 protected $m_typevalues;
2323
Index: trunk/extensions/SemanticMediaWiki/includes/datavalues/SMW_DV_Record.php
@@ -14,65 +14,95 @@
1515 * @author Markus Krötzsch
1616 * @ingroup SMWDataValues
1717 */
18 -class SMWRecordValue extends SMWContainerValue {
 18+class SMWRecordValue extends SMWDataValue {
1919
2020 /// cache for datavalues of types belonging to this object
2121 private $m_typevalues = null;
2222
2323 protected function parseUserValue( $value ) {
24 - $this->m_data->clear();
2524 $this->parseUserValueOrQuery( $value, false );
2625 }
2726
2827 protected function parseUserValueOrQuery( $value, $querymode ) {
2928 if ( $value == '' ) {
3029 $this->addError( wfMsg( 'smw_novalues' ) );
31 - return $querymode ? new SMWThingDescription() : $this->m_data;
 30+ if ( $querymode ) {
 31+ return new SMWThingDescription();
 32+ } else {
 33+ return;
 34+ }
3235 }
3336
34 - $subdescriptions = array(); // only used for query mode
 37+ if ( $querymode ) {
 38+ $subdescriptions = array();
 39+ } else {
 40+ $semanticData = new SMWContainerSemanticData();
 41+ }
 42+
3543 $types = $this->getTypeValues();
3644 $values = preg_split( '/[\s]*;[\s]*/u', trim( $value ) );
3745 $vi = 0; // index in value array
3846 $empty = true;
3947 for ( $i = 0; $i < max( 5, count( $types ) ); $i++ ) { // iterate over slots
40 - // special handling for supporting query parsing
41 - if ( $querymode ) {
 48+
 49+ if ( $querymode ) { // special handling for supporting query parsing
4250 $comparator = SMW_CMP_EQ;
4351 SMWDataValue::prepareValue( $values[$vi], $comparator );
4452 }
 53+
4554 // generating the DVs:
4655 if ( ( count( $values ) > $vi ) &&
4756 ( ( $values[$vi] == '' ) || ( $values[$vi] == '?' ) ) ) { // explicit omission
4857 $vi++;
4958 } elseif ( array_key_exists( $vi, $values ) && array_key_exists( $i, $types ) ) { // some values left, try next slot
50 - $dv = SMWDataValueFactory::newTypeObjectValue( $types[$i], $values[$vi] );
51 - if ( $dv->isValid() ) { // valid DV: keep
 59+ $dataValue = SMWDataValueFactory::newTypeObjectValue( $types[$i], $values[$vi] );
 60+ if ( $dataValue->isValid() ) { // valid DV: keep
5261 if ( $querymode ) {
53 - $subdescriptions[] = new SMWRecordFieldDescription( $i, new SMWValueDescription( $dv, $comparator ) );
 62+ $subdescriptions[] = new SMWRecordFieldDescription( $i, new SMWValueDescription( $dataValue->getDataItem(), $comparator ) );
5463 } else {
5564 $property = new SMWDIProperty( '_' . ( $i + 1 ) );
56 - $this->m_data->addPropertyObjectValue( $property, $dv );
 65+ $semanticData->addPropertyObjectValue( $property, $dataValue->getDataItem() );
5766 }
5867 $vi++;
5968 $empty = false;
6069 } elseif ( ( count( $values ) - $vi ) == ( count( $types ) - $i ) ) {
6170 // too many errors: keep this one to have enough slots left
62 - $this->m_data->addPropertyObjectValue( new SMWDIProperty( '_' . ( $i + 1 ) ), $dv );
63 - $this->addError( $dv->getErrors() );
 71+ if ( !$querymode ) {
 72+ $property = new SMWDIProperty( '_' . ( $i + 1 ) );
 73+ $semanticData->addPropertyObjectValue( $property, $dataValue->getDataItem() );
 74+ }
 75+ $this->addError( $dataValue->getErrors() );
6476 $vi++;
6577 }
6678 }
6779 }
 80+
6881 if ( $empty ) {
6982 $this->addError( wfMsg( 'smw_novalues' ) );
7083 }
 84+
7185 if ( $querymode ) {
7286 return $empty ? new SMWThingDescription() : new SMWRecordDescription( $subdescriptions );
 87+ } else {
 88+ $this->m_dataitem = new SMWDIContainer( $semanticData, $this->m_typeid );
7389 }
7490 }
7591
7692 /**
 93+ * @see SMWDataValue::setDataItem()
 94+ * @param $dataitem SMWDataItem
 95+ * @return boolean
 96+ */
 97+ public function setDataItem( SMWDataItem $dataItem ) {
 98+ if ( $dataItem->getDIType() == SMWDataItem::TYPE_CONTAINER ) {
 99+ $this->m_dataitem = $dataItem;
 100+ return true;
 101+ } else {
 102+ return false;
 103+ }
 104+ }
 105+
 106+ /**
77107 * This function resembles SMWContainerValue::parseDBkeys() but it already unstubs
78108 * the values instead of passing on initialisation strings. This is required since
79109 * the datatype of each entry is not determined by the property here (since we are
@@ -176,18 +206,23 @@
177207 ////// Additional API for value lists
178208
179209 /**
180 - * Create a list (array with numeric keys) containing the datavalue objects
181 - * that this SMWRecordValue object holds. Values that are not present are
182 - * set to null. Note that the first index in the array is 0, not 1.
 210+ * Create a list (array with numeric keys) containing the datavalue
 211+ * objects that this SMWRecordValue object holds. Values that are not
 212+ * present are set to null. Note that the first index in the array is
 213+ * 0, not 1.
 214+ *
 215+ * @todo This method should be renamed to getDataItems().
 216+ * @return array of SMWDataItem
183217 */
184218 public function getDVs() {
185219 if ( !$this->isValid() ) return array();
186220 $result = array();
187 - foreach ( $this->m_data->getProperties() as $prop ) {
 221+ $semanticData = $this->m_dataitem->getSemanticData();
 222+ foreach ( $semanticData->getProperties() as $prop ) {
188223 $propname = $prop->getPropertyID();
189224 $propnum = substr( $propname, 1 );
190225 if ( ( $propname != false ) && ( is_numeric( $propnum ) ) ) {
191 - $propertyvalues = $this->m_data->getPropertyValues( $prop ); // combining this with next line violates PHP strict standards
 226+ $propertyvalues = $semanticData->getPropertyValues( $prop ); // combining this with next line violates PHP strict standards
192227 $result[( $propnum - 1 )] = reset( $propertyvalues );
193228 }
194229 }
@@ -195,60 +230,121 @@
196231 }
197232
198233 /**
199 - * Return the array (list) of datatypes that the individual entries of this datatype consist of.
200 - * @todo Add some check to account for maximal number of list entries (maybe this should go to a
201 - * variant of the SMWTypesValue).
 234+ * Return the array (list) of datatypes that the individual entries of
 235+ * this datatype consist of.
 236+ *
 237+ * @todo Add some check to account for maximal number of list entries
 238+ * (maybe this should go to a variant of the SMWTypesValue).
 239+ * @todo I18N for error message.
 240+ * @return array of SMWTypesValue
202241 */
203242 public function getTypeValues() {
204 - if ( $this->m_typevalues !== null ) return $this->m_typevalues; // local cache
205 - if ( ( $this->m_property === null ) || ( $this->m_property->getWikiPageValue() === null ) ) {
206 - $this->m_typevalues = array(); // no property known -> no types
207 - } else { // query for type values
208 - $typelist = smwfGetStore()->getPropertyValues( $this->m_property->getWikiPageValue(), new SMWDIProperty( '_LIST' ) );
209 - if ( count( $typelist ) == 1 ) {
210 - $this->m_typevalues = reset( $typelist )->getTypeValues();
211 - } else { ///TODO internalionalize
 243+ if ( $this->m_typevalues === null ) {
 244+ $this->m_typevalues = self::findTypeValues( $this->m_property );
 245+ if ( count( $this->m_typevalues ) == 0 ) { //TODO internalionalize
212246 $this->addError( 'List type not properly specified for this property.' );
213 - $this->m_typevalues = array();
214247 }
215248 }
 249+
216250 return $this->m_typevalues;
217251 }
218252
 253+ /**
 254+ * Return the array (list) of datatypes that the individual entries of
 255+ * this datatype consist of.
 256+ *
 257+ * @param $diProperty SMWDIProperty object for which to retrieve the types
 258+ * @return array of SMWTypesValue
 259+ */
 260+ public static function findTypeValues( $diProperty ) {
 261+ if ( $diProperty !== null ) {
 262+ $propertyDiWikiPage = $diProperty->getDiWikiPage();
 263+ }
 264+
 265+ if ( ( $diProperty === null ) || ( $propertyDiWikiPage === null ) ) {
 266+ return array(); // no property known -> no types
 267+ } else { // query for type values
 268+ $listDiProperty = new SMWDIProperty( '_LIST' );
 269+ $dataitems = smwfGetStore()->getPropertyValues( $propertyDiWikiPage, $listDiProperty );
 270+ if ( count( $dataitems ) == 1 ) {
 271+ $typeListValue = new SMWTypeListValue( '__tls' );
 272+ $typeListValue->setDataItem( reset( $dataitems ) );
 273+ return $typeListValue->getTypeValues();
 274+ } else {
 275+ return array();
 276+ }
 277+ }
 278+ }
 279+
 280+ /**
 281+ * Return the array (list) of datatype ID that the individual entries
 282+ * of this datatype consist of.
 283+ *
 284+ * @note The architecture of Records and their types is flawed and needs
 285+ * improvement. The below code duplicates internals of SMWTypeListValue,
 286+ * but we do not care about this now.
 287+ * @param $diProperty SMWDIProperty object for which to retrieve the types
 288+ * @return array of string
 289+ */
 290+ public static function findTypeIds( $diProperty ) {
 291+ if ( $diProperty !== null ) {
 292+ $propertyDiWikiPage = $diProperty->getDiWikiPage();
 293+ }
 294+
 295+ if ( ( $diProperty === null ) || ( $propertyDiWikiPage === null ) ) {
 296+ return array(); // no property known -> no types
 297+ } else { // query for type values
 298+ $listDiProperty = new SMWDIProperty( '_LIST' );
 299+ $dataitems = smwfGetStore()->getPropertyValues( $propertyDiWikiPage, $listDiProperty );
 300+ if ( count( $dataitems ) == 1 ) {
 301+ return explode( ';', reset( $dataitems )->getString() );
 302+ } else {
 303+ return array();
 304+ }
 305+ }
 306+ }
 307+
219308 ////// Internal helper functions
220309
221 - private function makeOutputText( $type = 0, $linker = null ) {
 310+ protected function makeOutputText( $type = 0, $linker = null ) {
222311 if ( !$this->isValid() ) {
223312 return ( ( $type == 0 ) || ( $type == 1 ) ) ? '' : $this->getErrorText();
224313 }
 314+
225315 $result = '';
226316 for ( $i = 0; $i < count( $this->getTypeValues() ); $i++ ) {
227317 if ( $i == 1 ) {
228 - $result .= ( $type == 4 ) ? '; ':' (';
 318+ $result .= ( $type == 4 ) ? '; ' : ' (';
229319 } elseif ( $i > 1 ) {
230 - $result .= ( $type == 4 ) ? '; ':", ";
 320+ $result .= ( $type == 4 ) ? '; ' : ', ';
231321 }
232322 $property = new SMWDIProperty( '_' . ( $i + 1 ) );
233 - $propertyvalues = $this->m_data->getPropertyValues( $property ); // combining this with next line violates PHP strict standards
234 - $dv = reset( $propertyvalues );
235 - $result .= ( $dv !== false ) ? $this->makeValueOutputText( $type, $dv, $linker ): '?';
 323+ $propertyvalues = $this->m_dataitem->getSemanticData()->getPropertyValues( $property ); // combining this with next line violates PHP strict standards
 324+ $dataItem = reset( $propertyvalues );
 325+ if ( $dataItem !== false ) {
 326+ $dataValue = SMWDataValueFactory::newDataItemValue( $dataItem );
 327+ $result .= $this->makeValueOutputText( $type, $dataValue, $linker );
 328+ } else {
 329+ $result .= '?';
 330+ }
236331 }
237332 if ( ( $i > 1 ) && ( $type != 4 ) ) $result .= ')';
 333+
238334 return $result;
239335 }
240336
241 - private function makeValueOutputText( $type, $datavalue, $linker ) {
 337+ protected function makeValueOutputText( $type, $dataValue, $linker ) {
242338 switch ( $type ) {
243 - case 0: return $datavalue->getShortWikiText( $linker );
244 - case 1: return $datavalue->getShortHTMLText( $linker );
245 - case 2: return $datavalue->getShortWikiText( $linker );
246 - case 3: return $datavalue->getShortHTMLText( $linker );
247 - case 4: return $datavalue->getWikiValue();
 339+ case 0: return $dataValue->getShortWikiText( $linker );
 340+ case 1: return $dataValue->getShortHTMLText( $linker );
 341+ case 2: return $dataValue->getShortWikiText( $linker );
 342+ case 3: return $dataValue->getShortHTMLText( $linker );
 343+ case 4: return $dataValue->getWikiValue();
248344 }
249345 }
250346
251 - public function setDataItem( SMWDataItem $dataItem ) {
252 - // TODO: Make me do something
 347+ public function getDBkeys() {
 348+ return array();// no longer used
253349 }
254350 }
255351
Index: trunk/extensions/SemanticMediaWiki/includes/datavalues/SMW_DV_Container.php
@@ -14,23 +14,7 @@
1515 */
1616 abstract class SMWContainerValue extends SMWDataValue {
1717
18 - protected $m_data;
19 -
20 - public function __construct( $typeid ) {
21 - parent::__construct( $typeid );
22 - $this->m_data = new SMWSemanticData( null );
23 - }
24 -
2518 /**
26 - * We use the internal SMWSemanticData object to store some of this objects
27 - * data. Clone it to make sure that data can be modified independelty from
28 - * the original object's content.
29 - */
30 - public function __clone() {
31 - $this->m_data = clone $this->m_data; // note that this is always set
32 - }
33 -
34 - /**
3519 * Containers have one DB key, so the value of this function should be an array with one
3620 * element. This one DB key should consist of an array of arbitrary length where each
3721 * entry encodes one property-value pair. The pairs are encoded as arrays of size two
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_Factbox.php
@@ -87,7 +87,7 @@
8888 }
8989 }
9090 $i += 1;
91 - $dv = SMWDataValueFactory::newDataItemValue( $di );
 91+ $dv = SMWDataValueFactory::newDataItemValue( $di, false, $propertyDi );
9292 $text .= $dv->getLongWikiText( true ) . $dv->getInfolinkText( SMW_OUTPUT_WIKI );
9393 }
9494 $text .= '</td></tr>';
Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SqlStubSemanticData.php
@@ -86,7 +86,7 @@
8787
8888 foreach ( $this->mStubPropVals[$property->getKey()] as $dbkeys ) {
8989 try {
90 - $di = SMWCompatibilityHelpers::dataItemFromDBKeys( $property->findPropertyTypeID(), $dbkeys );
 90+ $di = SMWCompatibilityHelpers::dataItemFromDBKeys( $property->findPropertyTypeID(), $dbkeys, $property );
9191 if ( $this->mNoDuplicates ) {
9292 $this->mPropVals[$property->getKey()][$di->getHash()] = $di;
9393 } else {
Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_Store.php
@@ -162,6 +162,12 @@
163163 *
164164 * If called with $subject == null, all values for the given property
165165 * are returned.
 166+ *
 167+ * @param $subject mixed SMWDataItem or null
 168+ * @param $property SMWDIProperty
 169+ * @param $requestoptions SMWRequestOptions
 170+ *
 171+ * @return array of SMWDataItem
166172 */
167173 public abstract function getPropertyValues( $subject, SMWDIProperty $property, $requestoptions = null );
168174
Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SQLStore2.php
@@ -209,9 +209,9 @@
210210 /**
211211 * @see SMWStore::getPropertyValues
212212 *
213 - * @param SMWDataItem $subject
214 - * @param SMWDIProperty $property
215 - * @param SMWRequestOptions $requestoptions
 213+ * @param $subject mixed SMWDataItem or null
 214+ * @param $property SMWDIProperty
 215+ * @param $requestoptions SMWRequestOptions
216216 *
217217 * @return array of SMWDataItem
218218 */
@@ -515,17 +515,18 @@
516516 if ( $value instanceof SMWDIContainer ) { // recursive handling of containers
517517 $joinfield = "t$tableindex." . reset( array_keys( $proptable->objectfields ) ); // this must be a type 'p' object
518518 $proptables = self::getPropertyTables();
 519+ $semanticData = $value->getSemanticData();
519520
520 - foreach ( $value->getData()->getProperties() as $subproperty ) {
 521+ foreach ( $semanticData->getProperties() as $subproperty ) {
521522 $tableid = self::findPropertyTableID( $subproperty );
522523
523524 if ( ( $tableid == '' ) && ( $value !== null ) ) { // maybe a type-polymorphic property like _1; use value to find type
524 - $tableid = self::findTypeTableID( reset( $value->getData()->getPropertyValues( $subproperty ) )->getTypeID() );
 525+ $tableid = self::findTypeTableID( reset( $semanticData->getPropertyValues( $subproperty ) )->getTypeID() );
525526 }
526527
527528 $subproptable = $proptables[$tableid];
528529
529 - foreach ( $value->getData()->getPropertyValues( $subproperty ) as $subvalue ) {
 530+ foreach ( $semanticData->getPropertyValues( $subproperty ) as $subvalue ) {
530531 $tableindex++;
531532
532533 if ( $subproptable->idsubject ) { // simply add property table to check values
@@ -838,8 +839,13 @@
839840 * @param $pageid
840841 */
841842 protected function prepareDBUpdates( &$updates, SMWSemanticData $data, $pageid ) {
842 - $subject = $data->getSubject();
843 - $sid = ( $subject !== null ) ? $pageid:$this->makeSMWBnodeID( $pageid );
 843+ if ( $data instanceof SMWContainerSemanticData ) {
 844+ $sid = $this->makeSMWBnodeID( $pageid );
 845+ } else {
 846+ $subject = $data->getSubject();
 847+ $sid = $pageid;
 848+ }
 849+
844850 $proptables = self::getPropertyTables();
845851
846852 foreach ( $data->getProperties() as $property ) {
@@ -874,7 +880,7 @@
875881 }
876882
877883 if ( $di instanceof SMWDIContainer ) { // process subobjects recursively
878 - $bnode = $this->prepareDBUpdates( $updates, $di->getData(), $pageid );
 884+ $bnode = $this->prepareDBUpdates( $updates, $di->getSemanticData(), $pageid );
879885 // Note: tables for container objects MUST have objectfields == array(<somename> => 'p')
880886 reset( $proptable->objectfields );
881887 $uvals[key( $proptable->objectfields )] = $bnode;
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_CompatibilityHelpers.php
@@ -27,12 +27,13 @@
2828 * Throws SMWDataItemException if problems occur, to get our callers
2929 * used to it.
3030 *
31 - * @param $typeid id string for the given type
32 - * @param $dbkeys array of mixed
 31+ * @param $typeid string id for the given type
 32+ * @param $dbkeys array of mixed
 33+ * @param $diProperty mixed SMWDIProperty or null, the property for which this value is built, currently needed for records
3334 *
3435 * @return SMWDataItem
3536 */
36 - static public function dataItemFromDBKeys( $typeid, $dbkeys ) {
 37+ static public function dataItemFromDBKeys( $typeid, $dbkeys, $diProperty = null ) {
3738 switch ( SMWDataValueFactory::getDataItemId( $typeid ) ) {
3839 case SMWDataItem::TYPE_ERROR:
3940 break;
@@ -70,9 +71,30 @@
7172 break;
7273 case SMWDataItem::TYPE_GEO:
7374 return new SMWDIGeoCoord( array( 'lat' => (float)$dbkeys[0], 'lon' => (float)$dbkeys[1] ), $typeid );
74 - break;
7575 case SMWDataItem::TYPE_CONTAINER:
76 - break;
 76+ $semanticData = new SMWContainerSemanticData();
 77+ if ( $typeid == '_rec' ) {
 78+ $types = SMWRecordValue::findTypeIds( $diProperty );
 79+ foreach ( reset( $dbkeys ) as $value ) {
 80+ if ( is_array( $value ) && ( count( $value ) == 2 ) ) {
 81+ $diP = new SMWDIProperty( reset( $value ), false );
 82+ $pnum = intval( substr( reset( $value ), 1 ) ); // try to find the number of this property
 83+ if ( array_key_exists( $pnum - 1, $types ) ) {
 84+ $diV = self::dataItemFromDBKeys( $types[$pnum - 1], end( $value ) );
 85+ $semanticData->addPropertyObjectValue( $diP, $diV );
 86+ }
 87+ }
 88+ }
 89+ } else {
 90+ foreach ( reset( $dbkeys ) as $value ) {
 91+ if ( is_array( $value ) && ( count( $value ) == 2 ) ) {
 92+ $diP = new SMWDIProperty( reset( $value ), false );
 93+ $diV = self::dataItemFromDBKeys( $diP->findPropertyTypeID(), end( $value ) );
 94+ $semanticData->addPropertyObjectValue( $diP, $diV );
 95+ }
 96+ }
 97+ }
 98+ return new SMWDIContainer( $semanticData, $typeid );
7799 case SMWDataItem::TYPE_WIKIPAGE:
78100 if ( $typeid == '__typ' ) { // DBkeys for types values are special (used to be a SMWSimpleWikiPageValue)
79101 $pagedbkey = str_replace( ' ', '_', SMWDataValueFactory::findTypeLabel( $dbkeys[0] ) );
@@ -147,11 +169,11 @@
148170 return array( $dataItem->getKey() );
149171 case '_geo':
150172 $coordinateSet = $dataItem->getCoordinateSet();
151 -
 173+
152174 return array(
153175 $coordinateSet['lat'],
154176 $coordinateSet['lon']
155 - );
 177+ );
156178 break;
157179 default:
158180 $typeid = $dataItem->getTypeId();
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_SemanticData.php
@@ -175,14 +175,14 @@
176176 $ctx = hash_init( 'md5' );
177177
178178 if ( $this->mSubject !== null ) { // here and below, use "_#_" to separate values; really not much care needed here
179 - hash_update( $ctx, '_#_' . $this->mSubject->getSerialisation() );
 179+ hash_update( $ctx, '_#_' . $this->mSubject->getSerialization() );
180180 }
181181
182182 foreach ( $this->getProperties() as $property ) {
183183 hash_update( $ctx, '_#_' . $property->getKey() . '##' );
184184
185185 foreach ( $this->getPropertyValues( $property ) as $dv ) {
186 - hash_update( $ctx, '_#_' . $dv->getSerialisation() );
 186+ hash_update( $ctx, '_#_' . $dv->getSerialization() );
187187 }
188188 }
189189
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_DataValueFactory.php
@@ -59,10 +59,10 @@
6060 * given SMWTypesValue object specifies. If no $value is given, an empty
6161 * container is created, the value of which can be set later on.
6262 *
63 - * @param SMWTypesValue $typevalue Represents the type of the object
64 - * @param mixed $value user value string, or false if unknown
65 - * @param mixed $caption user-defined caption or false if none given
66 - * @param SMWDIProperty $property property object for which this value was made, or null
 63+ * @param $typevalue SMWTypesValue Represents the type of the object
 64+ * @param $value mixed user value string, or false if unknown
 65+ * @param $caption mixed user-defined caption or false if none given
 66+ * @param $property SMWDIProperty property object for which this value was made, or null
6767 */
6868 static public function newTypeObjectValue( SMWTypesValue $typeValue, $value = false, $caption = false, $property = null ) {
6969 if ( !$typeValue->isValid() ) { // just return the error, pass it through
@@ -112,9 +112,9 @@
113113 /**
114114 * Create a value for a data item.
115115 *
116 - * @param SMWDataItem $typeid id string for the given type
117 - * @param mixed $caption user-defined caption, or false if none given
118 - * @param SMWDIProperty $property property object for which this value is made, or NULL
 116+ * @param $typeid SMWDataItem id string for the given type
 117+ * @param $caption mixed user-defined caption, or false if none given
 118+ * @param $property SMWDIProperty property object for which this value is made, or NULL
119119 *
120120 * @return SMWDataValue
121121 */
Index: trunk/extensions/SemanticMediaWiki/includes/dataitems/SMW_DI_Container.php
@@ -32,10 +32,17 @@
3333 */
3434 public function __construct( $noDuplicates = true ) {
3535 $subject = new SMWDIWikiPage( 'SMWInternalObject', NS_SPECIAL, '' ); // dummy subject
36 - parent::__construct( $noDuplicates );
 36+ parent::__construct( $subject, $noDuplicates );
3737 }
3838
3939 /**
 40+ * Restore complete serialization which is disabled in SMWSemanticData.
 41+ */
 42+ public function __sleep() {
 43+ return array( 'mSubject', 'mProperties', 'mPropVals', 'mHasVisibleProps', 'mHasVisibleSpecs', 'mNoDuplicates' );
 44+ }
 45+
 46+ /**
4047 * Clone handler. Make any clone mutable again.
4148 */
4249 public function __clone() {
@@ -127,16 +134,30 @@
128135 }
129136
130137 public function getSerialization() {
131 - return $this->m_string;
 138+ return serialize( $this->m_semanticData );
132139 }
133140
134141 /**
 142+ * Get a hash string for this data item.
 143+ *
 144+ * @return string
 145+ */
 146+ public function getHash() {
 147+ return $this->m_semanticData->getHash();
 148+ }
 149+
 150+ /**
135151 * Create a data item from the provided serialization string and type
136152 * ID.
137153 * @return SMWDIContainer
138154 */
139155 public static function doUnserialize( $serialization, $typeid = '_rec' ) {
140 - return new SMWDIBlob( $serialization, $typeid );
 156+ /// TODO May issue an E_NOTICE when problems occur; catch this
 157+ $data = unserialize( $serialization );
 158+ if ( !( $data instanceof SMWContainerSemanticData ) ) {
 159+ throw SMWDataItemException( "Could not unserialize SMWDIContainer from the given string." );
 160+ }
 161+ return new SMWDIContainer( $data, $typeid );
141162 }
142163
143164 }

Status & tagging log