Index: trunk/extensions/SemanticMediaWiki/includes/SMW_ChangeSet.php |
— | — | @@ -69,7 +69,54 @@ |
70 | 70 | // Find the insertions. |
71 | 71 | self::findSingleDirectionChanges( $insertions, $newProperties, $new, $oldProperties ); |
72 | 72 | |
73 | | - // TODO: find one-to-one changes |
| 73 | + foreach ( $oldProperties as $propertyKey => /* SMWDIProperty */ $diProperty ) { |
| 74 | + $oldDataItems = array(); |
| 75 | + $newDataItems = array(); |
| 76 | + |
| 77 | + // Populate the data item arrays using keys that are their hash, so matches can be found. |
| 78 | + foreach ( $old->getPropertyValues( $diProperty ) as $dataItem ) { |
| 79 | + $oldDataItems[$dataItem->getHash()] = $dataItem; |
| 80 | + } |
| 81 | + foreach ( $new->getPropertyValues( $diProperty ) as $dataItem ) { |
| 82 | + $newDataItems[$dataItem->getHash()] = $dataItem; |
| 83 | + } |
| 84 | + |
| 85 | + $foundMatches = array(); |
| 86 | + |
| 87 | + // Find values that are both in the old and new version. |
| 88 | + // Note: this code assumes there are no duplicates. |
| 89 | + foreach ( array_keys( $oldDataItems ) as $hash ) { |
| 90 | + if ( array_key_exists( $hash, $newDataItems ) ) { |
| 91 | + $foundMatches[] = $hash; |
| 92 | + } |
| 93 | + } |
| 94 | + |
| 95 | + // Remove the values occuring in both sets, so only changes remain. |
| 96 | + foreach ( $foundMatches as $foundMatch ) { |
| 97 | + unset( $oldDataItems[$foundMatch] ); |
| 98 | + unset( $newDataItems[$foundMatch] ); |
| 99 | + } |
| 100 | + |
| 101 | + // Find which group is biggest, so it's easy to loop over all values of the smallest. |
| 102 | + $oldIsBigger = count( $oldDataItems ) > count ( $newDataItems ); |
| 103 | + $bigGroup = $oldIsBigger ? $oldDataItems : $newDataItems; |
| 104 | + $smallGroup = $oldIsBigger ? $newDataItems : $oldDataItems; |
| 105 | + |
| 106 | + // Add all one-to-one changes. |
| 107 | + while ( $dataItem = array_shift( $smallGroup ) ) { |
| 108 | + $changes->addPropertyObjectChange( $diProperty, new SMWPropertyChange( $dataItem, array_shift( $bigGroup ) ) ); |
| 109 | + } |
| 110 | + |
| 111 | + // If the bigger group is not-equal to the smaller one, items will be left, |
| 112 | + // that are either insertions or deletions, depending on the group. |
| 113 | + if ( count( $bigGroup > 0 ) ) { |
| 114 | + $semanticData = $oldIsBigger ? $deletions : $insertions; |
| 115 | + |
| 116 | + foreach ( $bigGroup as /* SMWDataItem */ $dataItem ) { |
| 117 | + $semanticData->addPropertyObjectValue( $diProperty, $dataItem ); |
| 118 | + } |
| 119 | + } |
| 120 | + } |
74 | 121 | |
75 | 122 | return new self( $subject, $changes, $insertions, $deletions ); |
76 | 123 | } |
— | — | @@ -101,8 +148,6 @@ |
102 | 149 | foreach ( $deletionKeys as $key ) { |
103 | 150 | unset( $oldProperties[$propertyKey] ); |
104 | 151 | } |
105 | | - |
106 | | - // TODO: handle props with multiple values (of which only some got inserted/removed) correctly |
107 | 152 | } |
108 | 153 | |
109 | 154 | /** |