Index: trunk/extensions/SemanticWatchlist/specials/SpecialSemanticWatchlist.php |
— | — | @@ -258,7 +258,8 @@ |
259 | 259 | 'format' => 'json', |
260 | 260 | 'swuserid' => $GLOBALS['wgUser']->getId(), |
261 | 261 | 'swlimit' => $limit, |
262 | | - 'swcontinue' => $continue |
| 262 | + 'swcontinue' => $continue, |
| 263 | + 'swmerge' => '1' |
263 | 264 | ); |
264 | 265 | |
265 | 266 | $api = new ApiMain( new FauxRequest( $requestData, true ), true ); |
Index: trunk/extensions/SemanticWatchlist/includes/SWL_PropertyChange.php |
— | — | @@ -96,5 +96,16 @@ |
97 | 97 | } |
98 | 98 | } |
99 | 99 | |
| 100 | + /** |
| 101 | + * Returns a serialized version of the change, suitable to |
| 102 | + * do equal comparisions but not to unserialize. |
| 103 | + * |
| 104 | + * @return string |
| 105 | + */ |
| 106 | + public function getSerialization() { |
| 107 | + return is_null( $this->oldValue ) ? '' : $this->oldValue->getSerialization() . '|' . |
| 108 | + is_null( $this->newValue ) ? '' : $this->newValue->getSerialization(); |
| 109 | + } |
| 110 | + |
100 | 111 | } |
101 | 112 | |
\ No newline at end of file |
Index: trunk/extensions/SemanticWatchlist/includes/SWL_ChangeSet.php |
— | — | @@ -376,6 +376,8 @@ |
377 | 377 | /** |
378 | 378 | * Adds a SWLPropertyChange to the set for the specified SMWDIProperty. |
379 | 379 | * |
| 380 | + * @since 0.1 |
| 381 | + * |
380 | 382 | * @param SMWDIProperty $property |
381 | 383 | * @param SWLPropertyChange $change |
382 | 384 | */ |
— | — | @@ -385,15 +387,39 @@ |
386 | 388 | $this->changes->addPropertyObjectChange( $property, $change ); |
387 | 389 | break; |
388 | 390 | case SWLPropertyChange::TYPE_INSERT: |
389 | | - $this->insertions->addPropertyObjectValue( $property, $change->getNewValue() ); |
| 391 | + $this->addInsertion( $property, $change->getNewValue() ); |
390 | 392 | break; |
391 | 393 | case SWLPropertyChange::TYPE_DELETE: |
392 | | - $this->deletions->addPropertyObjectValue( $property, $change->getOldValue() ); |
| 394 | + $this->addDeletion( $property, $change->getOldValue() ); |
393 | 395 | break; |
394 | 396 | } |
395 | 397 | } |
396 | 398 | |
397 | 399 | /** |
| 400 | + * Adds a SMWDataItem representing an insertion to the set for the specified SMWDIProperty. |
| 401 | + * |
| 402 | + * @since 0.1 |
| 403 | + * |
| 404 | + * @param SMWDIProperty $property |
| 405 | + * @param SMWDataItem $dataItem |
| 406 | + */ |
| 407 | + public function addInsertion( SMWDIProperty $property, SMWDataItem $dataItem ) { |
| 408 | + $this->insertions->addPropertyObjectValue( $property, $dataItem ); |
| 409 | + } |
| 410 | + |
| 411 | + /** |
| 412 | + * Adds a SMWDataItem representing a deletion to the set for the specified SMWDIProperty. |
| 413 | + * |
| 414 | + * @since 0.1 |
| 415 | + * |
| 416 | + * @param SMWDIProperty $property |
| 417 | + * @param SMWDataItem $dataItem |
| 418 | + */ |
| 419 | + public function addDeletion( SMWDIProperty $property, SMWDataItem $dataItem ) { |
| 420 | + $this->deletions->addPropertyObjectValue( $property, $dataItem ); |
| 421 | + } |
| 422 | + |
| 423 | + /** |
398 | 424 | * Returns a list of all properties. |
399 | 425 | * |
400 | 426 | * @return array of SMWDIProperty |
— | — | @@ -613,4 +639,104 @@ |
614 | 640 | return $this->edit; |
615 | 641 | } |
616 | 642 | |
| 643 | + /** |
| 644 | + * Returns if a certain insertion is present in the set of changes. |
| 645 | + * |
| 646 | + * @since 0.1 |
| 647 | + * |
| 648 | + * @param SMWDIProperty $property |
| 649 | + * @param string $value |
| 650 | + * |
| 651 | + * @return boolean |
| 652 | + */ |
| 653 | + public function hasInsertion( SMWDIProperty $property, $value ) { |
| 654 | + $has = false; |
| 655 | + |
| 656 | + foreach ( $this->insertions->getPropertyValues( $property ) as /* SMWDataItem */ $insertion ) { |
| 657 | + if ( $insertion->getSerialization() == $value ) { |
| 658 | + $has = true; |
| 659 | + break; |
| 660 | + } |
| 661 | + } |
| 662 | + |
| 663 | + return $has; |
| 664 | + } |
| 665 | + |
| 666 | + /** |
| 667 | + * Returns if a certain insertion is present in the set of changes. |
| 668 | + * |
| 669 | + * @since 0.1 |
| 670 | + * |
| 671 | + * @param SMWDIProperty $property |
| 672 | + * @param string $value |
| 673 | + * |
| 674 | + * @return boolean |
| 675 | + */ |
| 676 | + public function hasDeletion( SMWDIProperty $property, $value ) { |
| 677 | + $has = false; |
| 678 | + |
| 679 | + foreach ( $this->deletions->getPropertyValues( $property ) as /* SMWDataItem */ $deletion ) { |
| 680 | + if ( $deletion->getSerialization() == $value ) { |
| 681 | + $has = true; |
| 682 | + break; |
| 683 | + } |
| 684 | + } |
| 685 | + |
| 686 | + return $has; |
| 687 | + } |
| 688 | + |
| 689 | + /** |
| 690 | + * Returns if a certain change is present in the set of changes. |
| 691 | + * |
| 692 | + * @since 0.1 |
| 693 | + * |
| 694 | + * @param SMWDIProperty $property |
| 695 | + * @param SWLPropertyChange $change |
| 696 | + * |
| 697 | + * @return boolean |
| 698 | + */ |
| 699 | + public function hasChange( SMWDIProperty $property, SWLPropertyChange $change ) { |
| 700 | + $has = false; |
| 701 | + |
| 702 | + foreach ( $this->changes->getPropertyChanges( $property ) as /* SWLPropertyChange */ $propChange ) { |
| 703 | + if ( $propChange->getSerialization() == $change->getSerialization() ) { |
| 704 | + $has = true; |
| 705 | + break; |
| 706 | + } |
| 707 | + } |
| 708 | + |
| 709 | + return $has; |
| 710 | + } |
| 711 | + |
| 712 | + /** |
| 713 | + * Merges in the changes of another change set. |
| 714 | + * Duplicate changes are detected and only kept as a single change. |
| 715 | + * This is usefull for merging sets with (possibly overlapping) changes belonging to a single edit. |
| 716 | + * |
| 717 | + * @since 0.1 |
| 718 | + * |
| 719 | + * @param SWLChangeSet $set |
| 720 | + */ |
| 721 | + public function mergeInChangeSet( SWLChangeSet $set ) { |
| 722 | + foreach ( $set->getAllProperties() as $property ) { |
| 723 | + foreach ( $set->getChanges()->getPropertyChanges( $property ) as /* SWLPropertyChange */ $change ) { |
| 724 | + if ( !$this->hasChange( $property, $change ) ) { |
| 725 | + $this->addChange( $property, $change ); |
| 726 | + } |
| 727 | + } |
| 728 | + |
| 729 | + foreach ( $set->getInsertions()->getPropertyValues( $property ) as /* SMWDataItem */ $dataItem ) { |
| 730 | + if ( !$this->hasInsertion( $property, $dataItem ) ) { |
| 731 | + $this->addInsertion( $property, $dataItem ); |
| 732 | + } |
| 733 | + } |
| 734 | + |
| 735 | + foreach ( $set->getDeletions()->getPropertyValues( $property ) as /* SMWDataItem */ $dataItem ) { |
| 736 | + if ( !$this->hasInsertion( $property, $dataItem ) ) { |
| 737 | + $this->addDeletion( $property, $dataItem ); |
| 738 | + } |
| 739 | + } |
| 740 | + } |
| 741 | + } |
| 742 | + |
617 | 743 | } |
\ No newline at end of file |
Index: trunk/extensions/SemanticWatchlist/api/ApiQuerySemanticWatchlist.php |
— | — | @@ -52,9 +52,12 @@ |
53 | 53 | $this->mergeSets( $resultSets ); |
54 | 54 | } |
55 | 55 | |
56 | | - $this->getResult()->setIndexedTagName( $resultSets, 'set' ); |
| 56 | + //$this->getResult()->setIndexedTagName( $resultSets, 'set' ); |
57 | 57 | |
58 | 58 | foreach ( $resultSets as &$set ) { |
| 59 | + if ( !is_object( $set )) { |
| 60 | + var_dump($set);exit; |
| 61 | + } |
59 | 62 | $set = $set->toArray(); |
60 | 63 | |
61 | 64 | foreach ( $set['changes'] as $propName => $changes ) { |
— | — | @@ -135,8 +138,37 @@ |
136 | 139 | * |
137 | 140 | * @param array $sets |
138 | 141 | */ |
139 | | - protected function mergeSets( array &$sets ) { |
140 | | - // TODO |
| 142 | + protected function mergeSets( array &$sets ) { |
| 143 | + if ( count( $sets ) > 1 ) { |
| 144 | + $setsPerEdits = array(); |
| 145 | + |
| 146 | + // List the sets per edit. |
| 147 | + foreach ( $sets as $set ) { |
| 148 | + if ( !array_key_exists( $set->getEdit()->getId(), $setsPerEdits ) ) { |
| 149 | + $setsPerEdits[$set->getEdit()->getId()] = array(); |
| 150 | + } |
| 151 | + |
| 152 | + $setsPerEdits[$set->getEdit()->getId()][] = $set; |
| 153 | + } |
| 154 | + |
| 155 | + $mergedSets = array(); |
| 156 | + |
| 157 | + // For all edits with more then one set, merge all sets in the first one, |
| 158 | + // and add it to the $mergedSets list. |
| 159 | + foreach ( $setsPerEdits as $setsForEdit ) { |
| 160 | + $setCount = count( $setsForEdit ); |
| 161 | + |
| 162 | + if ( $setCount > 1 ) { |
| 163 | + for ( $i = 1; $i < $setCount; $i++ ) { |
| 164 | + $setsForEdit[0]->mergeInChangeSet( $setsForEdit[$i] ); |
| 165 | + } |
| 166 | + } |
| 167 | + |
| 168 | + $mergedSets[] = $setsForEdit[0]; |
| 169 | + } |
| 170 | + |
| 171 | + $sets = $mergedSets; |
| 172 | + } |
141 | 173 | } |
142 | 174 | |
143 | 175 | /** |
— | — | @@ -154,7 +186,7 @@ |
155 | 187 | ), |
156 | 188 | 'merge' => array( |
157 | 189 | ApiBase::PARAM_TYPE => 'boolean', |
158 | | - ApiBase::PARAM_TYPE => false, |
| 190 | + ApiBase::PARAM_DFLT => false, |
159 | 191 | ), |
160 | 192 | 'limit' => array( |
161 | 193 | ApiBase :: PARAM_DFLT => 20, |
— | — | @@ -165,6 +197,7 @@ |
166 | 198 | ), |
167 | 199 | 'continue' => null, |
168 | 200 | ); |
| 201 | + |
169 | 202 | } |
170 | 203 | |
171 | 204 | /** |