Index: trunk/extensions/SemanticWatchlist/specials/SpecialSemanticWatchlist.php |
— | — | @@ -338,7 +338,7 @@ |
339 | 339 | * Returns the HTML for the changes to a single propety. |
340 | 340 | * |
341 | 341 | * @param SMWDIProperty $property |
342 | | - * @param array of SMWPropertyChange $changes |
| 342 | + * @param array of SWLPropertyChange $changes |
343 | 343 | * |
344 | 344 | * @return string |
345 | 345 | */ |
— | — | @@ -347,7 +347,7 @@ |
348 | 348 | $deletions = array(); |
349 | 349 | |
350 | 350 | // Convert the changes into a list of insertions and a list of deletions. |
351 | | - foreach ( $changes as /* SMWPropertyChange */ $change ) { |
| 351 | + foreach ( $changes as /* SWLPropertyChange */ $change ) { |
352 | 352 | if ( !is_null( $change->getOldValue() ) ) { |
353 | 353 | $deletions[] = SMWDataValueFactory::newDataItemValue( $change->getOldValue(), $property )->getLongHTMLText(); |
354 | 354 | } |
Index: trunk/extensions/SemanticWatchlist/SemanticWatchlist.sql |
— | — | @@ -38,6 +38,13 @@ |
39 | 39 | set_time CHAR(14) binary NOT NULL default '' -- The time the chages where made |
40 | 40 | ) /*$wgDBTableOptions*/; |
41 | 41 | |
| 42 | +-- Links edits to watchlist groups. |
| 43 | +CREATE TABLE IF NOT EXISTS /*$wgDBprefix*/swl_edits_per_group ( |
| 44 | + epg_group_id SMALLINT unsigned NOT NULL, -- Foreign key: swl_groups.group_id |
| 45 | + epg_edit_id INT(10) unsigned NOT NULL, -- Edit ID |
| 46 | + PRIMARY KEY (epg_group_id,epg_edit_id) |
| 47 | +) /*$wgDBTableOptions*/; |
| 48 | + |
42 | 49 | -- Links change sets to watchlist groups. |
43 | 50 | CREATE TABLE IF NOT EXISTS /*$wgDBprefix*/swl_sets_per_group ( |
44 | 51 | spg_group_id SMALLINT unsigned NOT NULL, -- Foreign key: swl_groups.group_id |
Index: trunk/extensions/SemanticWatchlist/includes/SWL_PropertyChange.php |
— | — | @@ -0,0 +1,100 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/** |
| 5 | + * Represents a change to a semantic property. |
| 6 | + * |
| 7 | + * @since 0.1 |
| 8 | + * |
| 9 | + * @file SWL_PropertyChange.php |
| 10 | + * @ingroup SemanticWatchlist |
| 11 | + * |
| 12 | + * @licence GNU GPL v3 or later |
| 13 | + * @author Jeroen De Dauw < jeroendedauw@gmail.com > |
| 14 | + */ |
| 15 | +class SWLPropertyChange { |
| 16 | + |
| 17 | + const TYPE_INSERT = 0; |
| 18 | + const TYPE_UPDATE = 1; |
| 19 | + const TYPE_DELETE = 2; |
| 20 | + |
| 21 | + /** |
| 22 | + * The old value. |
| 23 | + * |
| 24 | + * @var SMWDataItem or null |
| 25 | + */ |
| 26 | + protected $oldValue; |
| 27 | + |
| 28 | + /** |
| 29 | + * The new value. |
| 30 | + * |
| 31 | + * @var SMWDataItem or null |
| 32 | + */ |
| 33 | + protected $newValue; |
| 34 | + |
| 35 | + /** |
| 36 | + * Creates and returns a new SWLPropertyChange instance from a serialization. |
| 37 | + * |
| 38 | + * @param string|null $oldValue |
| 39 | + * @param string|null $newValue |
| 40 | + * |
| 41 | + * @return SWLPropertyChange |
| 42 | + */ |
| 43 | + public static function newFromSerialization( SMWDIProperty $property, $oldValue, $newValue ) { |
| 44 | + $diType = SMWDataValueFactory::getDataItemId( $property->findPropertyTypeID() ); |
| 45 | + //var_dump($property); |
| 46 | + //if($diType!=7) {throw new Exception();exit;} |
| 47 | + return new self( |
| 48 | + is_null( $oldValue ) ? null : SMWDataItem::newFromSerialization( $diType, $oldValue ), |
| 49 | + is_null( $newValue ) ? null : SMWDataItem::newFromSerialization( $diType, $newValue ) |
| 50 | + ); |
| 51 | + } |
| 52 | + |
| 53 | + /** |
| 54 | + * Create a new SWLPropertyChange. |
| 55 | + * |
| 56 | + * @param SMWDataItem $oldValue |
| 57 | + * @param SMWDataItem $newValue |
| 58 | + */ |
| 59 | + public function __construct( /* SMWDataItem */ $oldValue, /* SMWDataItem */ $newValue ) { |
| 60 | + $this->oldValue = $oldValue; |
| 61 | + $this->newValue = $newValue; |
| 62 | + } |
| 63 | + |
| 64 | + /** |
| 65 | + * Retruns the old value, or null if there is none. |
| 66 | + * |
| 67 | + * @return SMWDataItem or null |
| 68 | + */ |
| 69 | + public function getOldValue() { |
| 70 | + return $this->oldValue; |
| 71 | + } |
| 72 | + |
| 73 | + |
| 74 | + /** |
| 75 | + * returns the new value, or null if there is none. |
| 76 | + * |
| 77 | + * @return SMWDataItem or null |
| 78 | + */ |
| 79 | + public function getNewValue() { |
| 80 | + return $this->newValue; |
| 81 | + } |
| 82 | + |
| 83 | + /** |
| 84 | + * Returns the type of the change. |
| 85 | + * |
| 86 | + * @return element of the SWLPropertyChange::TYPE_ enum |
| 87 | + */ |
| 88 | + public function getType() { |
| 89 | + if ( is_null( $this->oldValue ) ) { |
| 90 | + return self::TYPE_INSERT; |
| 91 | + } |
| 92 | + else if ( is_null( $this->newValue ) ) { |
| 93 | + return self::TYPE_DELETE; |
| 94 | + } |
| 95 | + else { |
| 96 | + return self::TYPE_UPDATE; |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | +} |
| 101 | + |
\ No newline at end of file |
Property changes on: trunk/extensions/SemanticWatchlist/includes/SWL_PropertyChange.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 102 | + native |
Index: trunk/extensions/SemanticWatchlist/includes/SWL_PropertyChanges.php |
— | — | @@ -0,0 +1,178 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/** |
| 5 | + * A collection of semantic properties and changes changes made to them. |
| 6 | + * This class is based on SMWSemanticData and can be seen as a simplified |
| 7 | + * version with SWLPropertyChange objects, each holding 2 SMWDataItem objects, |
| 8 | + * instead of SMWDataItem objects. |
| 9 | + * |
| 10 | + * @since 0.1 |
| 11 | + * |
| 12 | + * @file SWL_PropertyChange.php |
| 13 | + * @ingroup SemanticWatchlist |
| 14 | + * |
| 15 | + * @licence GNU GPL v3 or later |
| 16 | + * @author Jeroen De Dauw < jeroendedauw@gmail.com > |
| 17 | + */ |
| 18 | +class SWLPropertyChanges implements Iterator { |
| 19 | + |
| 20 | + protected $pos = 0; |
| 21 | + protected $currentRow = null; |
| 22 | + |
| 23 | + /** |
| 24 | + * Cache for the localized version of the namespace prefix "Property:". |
| 25 | + * |
| 26 | + * @var string |
| 27 | + */ |
| 28 | + static protected $propertyPrefix = ''; |
| 29 | + |
| 30 | + /** |
| 31 | + * Array mapping property keys (string) to arrays of SWLPropertyChange. |
| 32 | + * |
| 33 | + * @var array of SWLPropertyChange |
| 34 | + */ |
| 35 | + protected $changes = array(); |
| 36 | + |
| 37 | + /** |
| 38 | + * Array mapping property keys (string) to SMWDIProperty objects. |
| 39 | + * |
| 40 | + * @var array of SMWDIProperty |
| 41 | + */ |
| 42 | + protected $properties = array(); |
| 43 | + |
| 44 | + /** |
| 45 | + * Indicates if there are changes in the list. |
| 46 | + * |
| 47 | + * @var boolean |
| 48 | + */ |
| 49 | + protected $hasChanges = false; |
| 50 | + |
| 51 | + /** |
| 52 | + * Get the array of all properties that have changes. |
| 53 | + * |
| 54 | + * @return array of SMWDIProperty |
| 55 | + */ |
| 56 | + public function getProperties() { |
| 57 | + return $this->properties; |
| 58 | + } |
| 59 | + |
| 60 | + /** |
| 61 | + * Returns if the list contains any changes. |
| 62 | + * This info is cached, so the call is cheaper then doing a count. |
| 63 | + * |
| 64 | + * @return boolean |
| 65 | + */ |
| 66 | + public function hasChanges() { |
| 67 | + return $this->hasChanges; |
| 68 | + } |
| 69 | + |
| 70 | + /** |
| 71 | + * Get the array of all stored values for some property. |
| 72 | + * |
| 73 | + * @param $property SMWDIProperty |
| 74 | + * |
| 75 | + * @return array of SWLPropertyChange |
| 76 | + */ |
| 77 | + public function getPropertyChanges( SMWDIProperty $property ) { |
| 78 | + if ( array_key_exists( $property->getKey(), $this->changes ) ) { |
| 79 | + return $this->changes[$property->getKey()]; |
| 80 | + } else { |
| 81 | + return array(); |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | + /** |
| 86 | + * Store a value for a property identified by its SMWDataItem object. |
| 87 | + * |
| 88 | + * @note There is no check whether the type of the given data item |
| 89 | + * agrees with the type of the property. Since property types can |
| 90 | + * change, all parts of SMW are prepared to handle mismatched data item |
| 91 | + * types anyway. |
| 92 | + * |
| 93 | + * @param SMWDIProperty $property |
| 94 | + * @param SWLPropertyChange $change |
| 95 | + */ |
| 96 | + public function addPropertyObjectChange( SMWDIProperty $property, SWLPropertyChange $change ) { |
| 97 | + if ( $property->isInverse() ) { // inverse properties cannot be used for annotation |
| 98 | + return; |
| 99 | + } |
| 100 | + |
| 101 | + if ( !array_key_exists( $property->getKey(), $this->changes ) ) { |
| 102 | + $this->changes[$property->getKey()] = array(); |
| 103 | + $this->properties[$property->getKey()] = $property; |
| 104 | + } |
| 105 | + |
| 106 | + $this->changes[$property->getKey()][] = $change; |
| 107 | + |
| 108 | + $this->hasChanges = true; |
| 109 | + } |
| 110 | + |
| 111 | + /** |
| 112 | + * Store a value for a given property identified by its text label |
| 113 | + * (without namespace prefix). |
| 114 | + * |
| 115 | + * @param string $propertyName |
| 116 | + * @param SWLPropertyChange $change |
| 117 | + */ |
| 118 | + public function addPropertyChange( $propertyName, SWLPropertyChange $change ) { |
| 119 | + $propertyKey = smwfNormalTitleDBKey( $propertyName ); |
| 120 | + |
| 121 | + if ( array_key_exists( $propertyKey, $this->properties ) ) { |
| 122 | + $property = $this->properties[$propertyKey]; |
| 123 | + } else { |
| 124 | + if ( self::$propertyPrefix == '' ) { |
| 125 | + global $wgContLang; |
| 126 | + self::$propertyPrefix = $wgContLang->getNsText( SMW_NS_PROPERTY ) . ':'; |
| 127 | + } // explicitly use prefix to cope with things like [[Property:User:Stupid::somevalue]] |
| 128 | + |
| 129 | + $propertyDV = SMWPropertyValue::makeUserProperty( self::$propertyPrefix . $propertyName ); |
| 130 | + |
| 131 | + if ( !$propertyDV->isValid() ) { // error, maybe illegal title text |
| 132 | + return; |
| 133 | + } |
| 134 | + |
| 135 | + $property = $propertyDV->getDataItem(); |
| 136 | + } |
| 137 | + |
| 138 | + $this->addPropertyObjectChange( $property, $change ); |
| 139 | + } |
| 140 | + |
| 141 | + /** |
| 142 | + * Removes all changes for a certian property. |
| 143 | + * |
| 144 | + * @param SMWDIProperty $property |
| 145 | + */ |
| 146 | + public function removeChangesForProperty( SMWDIProperty $property ) { |
| 147 | + if ( array_key_exists( $property->getKey(), $this->changes ) ) { |
| 148 | + unset( $this->changes[$property->getKey()] ); |
| 149 | + unset( $this->properties[$property->getKey()] ); |
| 150 | + } |
| 151 | + } |
| 152 | + |
| 153 | + function rewind() { |
| 154 | + $this->pos = 0; |
| 155 | + $this->currentRow = null; |
| 156 | + } |
| 157 | + |
| 158 | + function current() { |
| 159 | + if ( is_null( $this->currentRow ) ) { |
| 160 | + $this->next(); |
| 161 | + } |
| 162 | + return $this->currentRow; |
| 163 | + } |
| 164 | + |
| 165 | + function key() { |
| 166 | + return $this->pos; |
| 167 | + } |
| 168 | + |
| 169 | + function next() { |
| 170 | + $this->pos++; |
| 171 | + $this->currentRow = array_key_exists( $this->pos, $this->changes ) ? $this->changes[$this->pos] : false; |
| 172 | + return $this->currentRow; |
| 173 | + } |
| 174 | + |
| 175 | + function valid() { |
| 176 | + return $this->current() !== false; |
| 177 | + } |
| 178 | + |
| 179 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/SemanticWatchlist/includes/SWL_PropertyChanges.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 180 | + native |
Index: trunk/extensions/SemanticWatchlist/includes/SWL_Emailer.php |
— | — | @@ -91,7 +91,7 @@ |
92 | 92 | $deletions = array(); |
93 | 93 | |
94 | 94 | // Convert the changes into a list of insertions and a list of deletions. |
95 | | - foreach ( $changes as /* SMWPropertyChange */ $change ) { |
| 95 | + foreach ( $changes as /* SWLPropertyChange */ $change ) { |
96 | 96 | if ( !is_null( $change->getOldValue() ) ) { |
97 | 97 | $deletions[] = SMWDataValueFactory::newDataItemValue( $change->getOldValue(), $property )->getShortHTMLText(); |
98 | 98 | } |
Index: trunk/extensions/SemanticWatchlist/includes/SWL_ChangeSet.php |
— | — | @@ -15,16 +15,34 @@ |
16 | 16 | class SWLChangeSet { |
17 | 17 | |
18 | 18 | /** |
19 | | - * Base object to which calls to unknown methods get routed via __call. |
20 | | - * This is to emulate SWLChangSet deriving from SMWChangeSet, but at the |
21 | | - * same time makes it possible to go from the SMW version to the SWL version |
22 | | - * by passing the former to the constructor of the later. |
| 19 | + * The subject the changes apply to. |
23 | 20 | * |
24 | | - * @var SMWChangeSet |
| 21 | + * @var SMWDIWikiPage |
25 | 22 | */ |
26 | | - protected $changeSet; |
| 23 | + protected $subject; |
27 | 24 | |
28 | 25 | /** |
| 26 | + * Object holding semantic data that got inserted. |
| 27 | + * |
| 28 | + * @var SMWSemanticData |
| 29 | + */ |
| 30 | + protected $insertions; |
| 31 | + |
| 32 | + /** |
| 33 | + * Object holding semantic data that got deleted. |
| 34 | + * |
| 35 | + * @var SMWSemanticData |
| 36 | + */ |
| 37 | + protected $deletions; |
| 38 | + |
| 39 | + /** |
| 40 | + * List of all changes(, not including insertions and deletions). |
| 41 | + * |
| 42 | + * @var SWLPropertyChanges |
| 43 | + */ |
| 44 | + protected $changes; |
| 45 | + |
| 46 | + /** |
29 | 47 | * The user that made the changes. |
30 | 48 | * |
31 | 49 | * @var User |
— | — | @@ -90,7 +108,7 @@ |
91 | 109 | |
92 | 110 | $changeSet->addChange( |
93 | 111 | $property, |
94 | | - SMWPropertyChange::newFromSerialization( $property, $change->change_old_value, $change->change_new_value ) |
| 112 | + SWLPropertyChange::newFromSerialization( $property, $change->change_old_value, $change->change_new_value ) |
95 | 113 | ); |
96 | 114 | } |
97 | 115 | |
— | — | @@ -125,7 +143,7 @@ |
126 | 144 | foreach ( $changes as $change ) { |
127 | 145 | $changeSet->addChange( |
128 | 146 | $property, |
129 | | - SMWPropertyChange::newFromSerialization( |
| 147 | + SWLPropertyChange::newFromSerialization( |
130 | 148 | $property, |
131 | 149 | array_key_exists( 'old', $change ) ? $change['old'] : null, |
132 | 150 | array_key_exists( 'new', $change ) ? $change['new'] : null |
— | — | @@ -145,36 +163,255 @@ |
146 | 164 | } |
147 | 165 | |
148 | 166 | /** |
149 | | - * Constructor. |
| 167 | + * Creates and returns a new SMWChangeSet from 2 SMWSemanticData objects. |
150 | 168 | * |
151 | | - * @since 0.1 |
| 169 | + * @param SMWSemanticData $old |
| 170 | + * @param SMWSemanticData $new |
152 | 171 | * |
153 | | - * @param SMWChangeSet $changeSet |
154 | | - * @param User $user |
155 | | - * @param integer $time |
156 | | - * @param integer $id |
| 172 | + * @return SMWChangeSet |
157 | 173 | */ |
158 | | - public function __construct( SMWChangeSet $changeSet, /* User */ $user = null, $time = null, $id = null ) { |
159 | | - $this->changeSet = $changeSet; |
| 174 | + public static function newFromSemanticData( SMWSemanticData $old, SMWSemanticData $new ) { |
| 175 | + $subject = $old->getSubject(); |
| 176 | + |
| 177 | + if ( $subject != $new->getSubject() ) { |
| 178 | + return new self( $subject ); |
| 179 | + } |
| 180 | + |
| 181 | + $changes = new SWLPropertyChanges(); |
| 182 | + $insertions = new SMWSemanticData( $subject ); |
| 183 | + $deletions = new SMWSemanticData( $subject ); |
| 184 | + |
| 185 | + $oldProperties = $old->getProperties(); |
| 186 | + $newProperties = $new->getProperties(); |
| 187 | + |
| 188 | + // Find the deletions. |
| 189 | + self::findSingleDirectionChanges( $deletions, $oldProperties, $old, $newProperties ); |
| 190 | + |
| 191 | + // Find the insertions. |
| 192 | + self::findSingleDirectionChanges( $insertions, $newProperties, $new, $oldProperties ); |
| 193 | + |
| 194 | + foreach ( $oldProperties as $propertyKey => /* SMWDIProperty */ $diProperty ) { |
| 195 | + $oldDataItems = array(); |
| 196 | + $newDataItems = array(); |
| 197 | + |
| 198 | + // Populate the data item arrays using keys that are their hash, so matches can be found. |
| 199 | + // Note: this code assumes there are no duplicates. |
| 200 | + foreach ( $old->getPropertyValues( $diProperty ) as /* SMWDataItem */ $dataItem ) { |
| 201 | + $oldDataItems[$dataItem->getHash()] = $dataItem; |
| 202 | + } |
| 203 | + foreach ( $new->getPropertyValues( $diProperty ) as /* SMWDataItem */ $dataItem ) { |
| 204 | + $newDataItems[$dataItem->getHash()] = $dataItem; |
| 205 | + } |
| 206 | + |
| 207 | + $foundMatches = array(); |
| 208 | + |
| 209 | + // Find values that are both in the old and new version. |
| 210 | + foreach ( array_keys( $oldDataItems ) as $hash ) { |
| 211 | + if ( array_key_exists( $hash, $newDataItems ) ) { |
| 212 | + $foundMatches[] = $hash; |
| 213 | + } |
| 214 | + } |
| 215 | + |
| 216 | + // Remove the values occuring in both sets, so only changes remain. |
| 217 | + foreach ( $foundMatches as $foundMatch ) { |
| 218 | + unset( $oldDataItems[$foundMatch] ); |
| 219 | + unset( $newDataItems[$foundMatch] ); |
| 220 | + } |
| 221 | + |
| 222 | + // Find which group is biggest, so it's easy to loop over all values of the smallest. |
| 223 | + $oldIsBigger = count( $oldDataItems ) > count ( $newDataItems ); |
| 224 | + $bigGroup = $oldIsBigger ? $oldDataItems : $newDataItems; |
| 225 | + $smallGroup = $oldIsBigger ? $newDataItems : $oldDataItems; |
| 226 | + |
| 227 | + // Add all one-to-one changes. |
| 228 | + while ( $dataItem = array_shift( $smallGroup ) ) { |
| 229 | + $changes->addPropertyObjectChange( $diProperty, new SWLPropertyChange( $dataItem, array_shift( $bigGroup ) ) ); |
| 230 | + } |
| 231 | + |
| 232 | + // If the bigger group is not-equal to the smaller one, items will be left, |
| 233 | + // that are either insertions or deletions, depending on the group. |
| 234 | + if ( count( $bigGroup > 0 ) ) { |
| 235 | + $semanticData = $oldIsBigger ? $deletions : $insertions; |
| 236 | + |
| 237 | + foreach ( $bigGroup as /* SMWDataItem */ $dataItem ) { |
| 238 | + $semanticData->addPropertyObjectValue( $diProperty, $dataItem ); |
| 239 | + } |
| 240 | + } |
| 241 | + } |
| 242 | + |
| 243 | + return new self( $subject, $changes, $insertions, $deletions ); |
| 244 | + } |
| 245 | + |
| 246 | + /** |
| 247 | + * Finds the inserts or deletions and adds them to the passed SMWSemanticData object. |
| 248 | + * These values will also be removed from the first list of properties and their values, |
| 249 | + * so it can be used for one-to-one change finding later on. |
| 250 | + * |
| 251 | + * @param SMWSemanticData $changeSet |
| 252 | + * @param array $oldProperties |
| 253 | + * @param SMWSemanticData $oldData |
| 254 | + * @param array $newProperties |
| 255 | + */ |
| 256 | + protected static function findSingleDirectionChanges( SMWSemanticData &$changeSet, |
| 257 | + array &$oldProperties, SMWSemanticData $oldData, array $newProperties ) { |
| 258 | + |
| 259 | + $deletionKeys = array(); |
| 260 | + |
| 261 | + foreach ( $oldProperties as $propertyKey => /* SMWDIProperty */ $diProperty ) { |
| 262 | + if ( !array_key_exists( $propertyKey, $newProperties ) ) { |
| 263 | + foreach ( $oldData->getPropertyValues( $diProperty ) as /* SMWDataItem */ $dataItem ) { |
| 264 | + $changeSet->addPropertyObjectValue( $diProperty, $dataItem ); |
| 265 | + } |
| 266 | + $deletionKeys[] = $propertyKey; |
| 267 | + } |
| 268 | + } |
| 269 | + |
| 270 | + foreach ( $deletionKeys as $key ) { |
| 271 | + unset( $oldProperties[$propertyKey] ); |
| 272 | + } |
| 273 | + } |
| 274 | + |
| 275 | + /** |
| 276 | + * Create a new instance of a change set. |
| 277 | + * |
| 278 | + * @param SMWDIWikiPage $subject |
| 279 | + * @param SWLPropertyChanges $changes Can be null |
| 280 | + * @param SMWSemanticData $insertions Can be null |
| 281 | + * @param SMWSemanticData $deletions Can be null |
| 282 | + */ |
| 283 | + public function __construct( SMWDIWikiPage $subject, /* SWLPropertyChanges */ $changes = null, |
| 284 | + /* SMWSemanticData */ $insertions = null, /* SMWSemanticData */ $deletions = null, |
| 285 | + /* User */ $user = null, $time = null, $id = null ) { |
| 286 | + |
| 287 | + $this->subject = $subject; |
| 288 | + $this->changes = is_null( $changes ) ? new SWLPropertyChanges() : $changes; |
| 289 | + $this->insertions = is_null( $insertions ) ? new SMWSemanticData( $subject ): $insertions; |
| 290 | + $this->deletions = is_null( $deletions ) ? new SMWSemanticData( $subject ): $deletions; |
| 291 | + |
160 | 292 | $this->time = is_null( $time ) ? wfTimestampNow() : $time; |
161 | 293 | $this->user = is_null( $user ) ? $GLOBALS['wgUser'] : $user; |
162 | 294 | $this->id = $id; |
163 | 295 | } |
164 | 296 | |
165 | 297 | /** |
166 | | - * SMW thinks this class is a SMWResultPrinter, and calls methods that should |
167 | | - * be forewarded to $this->queryPrinter on it. |
| 298 | + * Returns whether the set contains any changes. |
168 | 299 | * |
169 | | - * @since 0.1 |
| 300 | + * @param boolean $refresh |
170 | 301 | * |
171 | | - * @param string $name |
172 | | - * @param array $arguments |
| 302 | + * @return boolean |
173 | 303 | */ |
174 | | - public function __call( $name, array $arguments ) { |
175 | | - return call_user_func_array( array( $this->changeSet, $name ), $arguments ); |
| 304 | + public function hasChanges( $refresh = false ) { |
| 305 | + return $this->changes->hasChanges() |
| 306 | + || $this->insertions->hasVisibleProperties( $refresh ) |
| 307 | + || $this->deletions->hasVisibleProperties( $refresh ); |
176 | 308 | } |
177 | 309 | |
178 | 310 | /** |
| 311 | + * Returns a SMWSemanticData object holding all inserted SMWDataItem objects. |
| 312 | + * |
| 313 | + * @return SMWSemanticData |
| 314 | + */ |
| 315 | + public function getInsertions() { |
| 316 | + return $this->insertions; |
| 317 | + } |
| 318 | + |
| 319 | + /** |
| 320 | + * Returns a SMWSemanticData object holding all deleted SMWDataItem objects. |
| 321 | + * |
| 322 | + * @return SMWSemanticData |
| 323 | + */ |
| 324 | + public function getDeletions() { |
| 325 | + return $this->deletions; |
| 326 | + } |
| 327 | + |
| 328 | + /** |
| 329 | + * Returns a SWLPropertyChanges object holding all SWLPropertyChange objects. |
| 330 | + * |
| 331 | + * @return SWLPropertyChanges |
| 332 | + */ |
| 333 | + public function getChanges() { |
| 334 | + return $this->changes; |
| 335 | + } |
| 336 | + |
| 337 | + /** |
| 338 | + * Returns the subject these changes apply to. |
| 339 | + * |
| 340 | + * @return SMWDIWikiPage |
| 341 | + */ |
| 342 | + public function getSubject() { |
| 343 | + return $this->subject; |
| 344 | + } |
| 345 | + |
| 346 | + /** |
| 347 | + * Adds a SWLPropertyChange to the set for the specified SMWDIProperty. |
| 348 | + * |
| 349 | + * @param SMWDIProperty $property |
| 350 | + * @param SWLPropertyChange $change |
| 351 | + */ |
| 352 | + public function addChange( SMWDIProperty $property, SWLPropertyChange $change ) { |
| 353 | + switch ( $change->getType() ) { |
| 354 | + case SWLPropertyChange::TYPE_UPDATE: |
| 355 | + $this->changes->addPropertyObjectChange( $property, $change ); |
| 356 | + break; |
| 357 | + case SWLPropertyChange::TYPE_INSERT: |
| 358 | + $this->insertions->addPropertyObjectValue( $property, $change->getNewValue() ); |
| 359 | + break; |
| 360 | + case SWLPropertyChange::TYPE_DELETE: |
| 361 | + $this->deletions->addPropertyObjectValue( $property, $change->getOldValue() ); |
| 362 | + break; |
| 363 | + } |
| 364 | + } |
| 365 | + |
| 366 | + /** |
| 367 | + * Returns a list of all properties. |
| 368 | + * |
| 369 | + * @return array of SMWDIProperty |
| 370 | + */ |
| 371 | + public function getAllProperties() { |
| 372 | + return array_merge( |
| 373 | + $this->getChanges()->getProperties(), |
| 374 | + $this->getInsertions()->getProperties(), |
| 375 | + $this->getDeletions()->getProperties() |
| 376 | + ); |
| 377 | + } |
| 378 | + |
| 379 | + /** |
| 380 | + * Removes all changes for a certian property. |
| 381 | + * |
| 382 | + * @param SMWDIProperty $property |
| 383 | + */ |
| 384 | + public function removeChangesForProperty( SMWDIProperty $property ) { |
| 385 | + $this->getChanges()->removeChangesForProperty( $property ); |
| 386 | + $this->getInsertions()->removeDataForProperty( $property ); |
| 387 | + $this->getDeletions()->removeDataForProperty( $property ); |
| 388 | + } |
| 389 | + |
| 390 | + /** |
| 391 | + * Returns a list of ALL changes, including isertions and deletions. |
| 392 | + * |
| 393 | + * @param SMWDIProperty $proprety |
| 394 | + * |
| 395 | + * @return array of SWLPropertyChange |
| 396 | + */ |
| 397 | + public function getAllPropertyChanges( SMWDIProperty $property ) { |
| 398 | + $changes = array(); |
| 399 | + |
| 400 | + foreach ( $this->changes->getPropertyChanges( $property ) as /* SWLPropertyChange */ $change ) { |
| 401 | + $changes[] = $change; |
| 402 | + } |
| 403 | + |
| 404 | + foreach ( $this->insertions->getPropertyValues( $property ) as /* SMWDataItem */ $dataItem ) { |
| 405 | + $changes[] = new SWLPropertyChange( null, $dataItem ); |
| 406 | + } |
| 407 | + |
| 408 | + foreach ( $this->deletions->getPropertyValues( $property ) as /* SMWDataItem */ $dataItem ) { |
| 409 | + $changes[] = new SWLPropertyChange( $dataItem, null ); |
| 410 | + } |
| 411 | + |
| 412 | + return $changes; |
| 413 | + } |
| 414 | + |
| 415 | + /** |
179 | 416 | * Serializes the object as an associative array, which can be passed |
180 | 417 | * to newFromArray to create a new instance. |
181 | 418 | * |
— | — | @@ -191,10 +428,10 @@ |
192 | 429 | 'changes' => array() |
193 | 430 | ); |
194 | 431 | |
195 | | - foreach ( $this->changeSet->getAllProperties() as /* SMWDIProperty */ $property ) { |
| 432 | + foreach ( $this->getAllProperties() as /* SMWDIProperty */ $property ) { |
196 | 433 | $propChanges = array(); |
197 | 434 | |
198 | | - foreach ( $this->changeSet->getAllPropertyChanges( $property ) as /* SMWPropertyChange */ $change ) { |
| 435 | + foreach ( $this->getAllPropertyChanges( $property ) as /* SWLPropertyChange */ $change ) { |
199 | 436 | $propChange = array(); |
200 | 437 | |
201 | 438 | if ( is_object( $change->getOldValue() ) ) { |
— | — | @@ -256,7 +493,7 @@ |
257 | 494 | if ( $property->isUserDefined() ) { |
258 | 495 | $propSerialization = $property->getSerialization(); |
259 | 496 | |
260 | | - foreach ( $this->getChanges()->getPropertyChanges( $property ) as /* SMWPropertyChange */ $change ) { |
| 497 | + foreach ( $this->getChanges()->getPropertyChanges( $property ) as /* SWLPropertyChange */ $change ) { |
261 | 498 | $changes[] = array( |
262 | 499 | 'property' => $propSerialization, |
263 | 500 | 'old' => $change->getOldValue()->getSerialization(), |
— | — | @@ -371,9 +608,10 @@ |
372 | 609 | * @param array $properties List of property names |
373 | 610 | */ |
374 | 611 | public function filterOnProperties( array $properties ) { |
| 612 | + // TODO |
375 | 613 | foreach ( $this->getAllProperties() as /* SMWDIProperty */ $property ) { |
376 | 614 | if ( !in_array( $property->getSerialization(), $properties ) ) { |
377 | | - $this->changeSet->removeChangesForProperty( $property ); |
| 615 | + //$this->changeSet->removeChangesForProperty( $property ); |
378 | 616 | } |
379 | 617 | } |
380 | 618 | } |
Index: trunk/extensions/SemanticWatchlist/SemanticWatchlist.php |
— | — | @@ -66,6 +66,8 @@ |
67 | 67 | $wgAutoloadClasses['SWLEmailer'] = dirname( __FILE__ ) . '/includes/SWL_Emailer.php'; |
68 | 68 | $wgAutoloadClasses['SWLGroup'] = dirname( __FILE__ ) . '/includes/SWL_Group.php'; |
69 | 69 | $wgAutoloadClasses['SWLGroups'] = dirname( __FILE__ ) . '/includes/SWL_Groups.php'; |
| 70 | +$wgAutoloadClasses['SWLPropertyChange'] = dirname( __FILE__ ) . '/includes/SWL_PropertyChange.php'; |
| 71 | +$wgAutoloadClasses['SWLPropertyChanges'] = dirname( __FILE__ ) . '/includes/SWL_PropertyChanges.php'; |
70 | 72 | |
71 | 73 | $wgAutoloadClasses['SpecialSemanticWatchlist'] = dirname( __FILE__ ) . '/specials/SpecialSemanticWatchlist.php'; |
72 | 74 | $wgAutoloadClasses['SpecialWatchlistConditions'] = dirname( __FILE__ ) . '/specials/SpecialWatchlistConditions.php'; |
— | — | @@ -83,7 +85,7 @@ |
84 | 86 | |
85 | 87 | $wgHooks['LoadExtensionSchemaUpdates'][] = 'SWLHooks::onSchemaUpdate'; |
86 | 88 | |
87 | | -$wgHooks['SMWStore::dataChanged'][] = 'SWLHooks::onDataChanged'; |
| 89 | +$wgHooks['SMWStore::updateDataBefore'][] = 'SWLHooks::onDataUpdate'; |
88 | 90 | |
89 | 91 | $wgHooks['GetPreferences'][] = 'SWLHooks::onGetPreferences'; |
90 | 92 | |
Index: trunk/extensions/SemanticWatchlist/SemanticWatchlist.hooks.php |
— | — | @@ -24,8 +24,8 @@ |
25 | 25 | * |
26 | 26 | * @return true |
27 | 27 | */ |
28 | | - public static function onDataChanged( SMWStore $store, SMWChangeSet $changes ) { |
29 | | - $changes = new SWLChangeSet( $changes ); |
| 28 | + public static function onDataUpdate( SMWStore $store, SMWSemanticData $newData ) { |
| 29 | + $changes = SWLChangeSet::newFromSemanticData( $store->getSemanticData( $newData->getSubject() ), $newData ); |
30 | 30 | $groups = SWLGroups::getMatchingWatchGroups( $changes->getTitle() ); |
31 | 31 | |
32 | 32 | $wasInserted = $changes->writeToStore( $groups ) != 0; |
— | — | @@ -213,6 +213,12 @@ |
214 | 214 | ) ); |
215 | 215 | $updater->addExtensionUpdate( array( |
216 | 216 | 'addTable', |
| 217 | + 'swl_edits_per_group', |
| 218 | + dirname( __FILE__ ) . '/SemanticWatchlist.sql', |
| 219 | + true |
| 220 | + ) ); |
| 221 | + $updater->addExtensionUpdate( array( |
| 222 | + 'addTable', |
217 | 223 | 'swl_sets_per_group', |
218 | 224 | dirname( __FILE__ ) . '/SemanticWatchlist.sql', |
219 | 225 | true |