BUGFIX #5138: DataObjectSet::removeDuplicates() removes objects of different classes with the same ID (from r100896)

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@111535 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sam Minnee 2010-10-04 04:15:33 +00:00
parent e55102ef29
commit a9ab6321bc
2 changed files with 21 additions and 7 deletions

View File

@ -827,11 +827,11 @@ class DataObjectSet extends ViewableData implements IteratorAggregate, Countable
public function removeDuplicates($field = 'ID') { public function removeDuplicates($field = 'ID') {
$exists = array(); $exists = array();
foreach($this->items as $key => $item) { foreach($this->items as $key => $item) {
if(isset($exists[$item->$field])) { if(isset($exists[$fullkey = ClassInfo::baseDataClass($item) . ":" . $item->$field])) {
unset($this->items[$key]); unset($this->items[$key]);
} }
$exists[$item->$field] = true; $exists[$fullkey] = true;
} }
} }
/** /**

View File

@ -208,8 +208,10 @@ class DataObjectSetTest extends SapphireTest {
/* There are 9 items in the map. 8 are records. 1 is the empty value */ /* There are 9 items in the map. 8 are records. 1 is the empty value */
$this->assertEquals(count($map), 9, 'There are 9 items in the map. 8 are records. 1 is the empty value.'); $this->assertEquals(count($map), 9, 'There are 9 items in the map. 8 are records. 1 is the empty value.');
} }
function testRemoveDuplicates() { function testRemoveDuplicates() {
// Note that PageComment and DataObjectSetTest_TeamComment are both descendants of DataObject, and don't
// share an inheritance relationship below that.
$pageComments = DataObject::get('PageComment'); $pageComments = DataObject::get('PageComment');
$teamComments = DataObject::get('DataObjectSetTest_TeamComment'); $teamComments = DataObject::get('DataObjectSetTest_TeamComment');
@ -222,19 +224,31 @@ class DataObjectSetTest extends SapphireTest {
$allComments->removeDuplicates(); $allComments->removeDuplicates();
$this->assertEquals($allComments->Count(), 8, 'Standard functionality is to remove duplicate IDs'); $this->assertEquals($allComments->Count(), 11, 'Standard functionality is to remove duplicate base class/IDs');
/* Now test removing duplicates based on a common field. In this case we shall /* Now test removing duplicates based on a common field. In this case we shall
* use 'Name', so we can get all the unique commentators */ * use 'Name', so we can get all the unique commentators */
$allComments = new DataObjectSet(); $allComments = new DataObjectSet();
$allComments->merge($pageComments); $allComments->merge($pageComments);
$allComments->merge($teamComments); $allComments->merge($teamComments);
$allComments->removeDuplicates('Name'); $allComments->removeDuplicates('Name');
$this->assertEquals($allComments->Count(), 7, 'There are 7 uniquely named commentators'); $this->assertEquals($allComments->Count(), 9, 'There are 9 uniquely named commentators');
// Ensure that duplicates are removed where the base data class is the same.
$mixedSet = new DataObjectSet();
$mixedSet->push(new SiteTree(array('ID' => 1)));
$mixedSet->push(new Page(array('ID' => 1))); // dup: same base class and ID
$mixedSet->push(new Page(array('ID' => 1))); // dup: more than one dup of the same object
$mixedSet->push(new Page(array('ID' => 2))); // not dup: same type again, but different ID
$mixedSet->push(new PageComment(array('ID' => 1))); // not dup: different base type, same ID
$mixedSet->push(new SiteTree(array('ID' => 1))); // dup: another dup, not consequetive.
$mixedSet->removeDuplicates('ID');
$this->assertEquals($mixedSet->Count(), 3, 'There are 3 unique data objects in a very mixed set');
} }
/** /**