ENHANCEMENT Allowing to save ManyManyList with multiple foreign keys (e.g. required to add to an overloaded Group->Members() relationship)

This commit is contained in:
Ingo Schommer 2012-03-06 16:34:51 +01:00
parent 861785958a
commit 51bae9e4a6
5 changed files with 41 additions and 17 deletions

View File

@ -62,7 +62,7 @@ class DataQuery {
}
}
if(!$matched) user_error("Couldn't find $fieldExpression in the query filter.", E_USER_WARNING);
if(!$matched) throw new InvalidArgumentException("Couldn't find $fieldExpression in the query filter.");
return $this;
}

View File

@ -93,25 +93,24 @@ class ManyManyList extends RelationList {
if(!$this->foreignID) {
throw new Exception("ManyManyList::add() can't be called until a foreign ID is set", E_USER_WARNING);
}
if(is_array($this->foreignID)) {
throw new Exception("ManyManyList::add() can't be called on a list linked to mulitple foreign IDs", E_USER_WARNING);
}
// Delete old entries, to prevent duplication
$this->removeById($itemID);
// Insert new entry
$manipulation = array();
$manipulation[$this->joinTable]['command'] = 'insert';
// Insert new entry/entries
foreach((array)$this->foreignID as $foreignID) {
$manipulation = array();
$manipulation[$this->joinTable]['command'] = 'insert';
if($extraFields) foreach($extraFields as $k => $v) {
$manipulation[$this->joinTable]['fields'][$k] = "'" . Convert::raw2sql($v) . "'";
if($extraFields) foreach($extraFields as $k => $v) {
$manipulation[$this->joinTable]['fields'][$k] = "'" . Convert::raw2sql($v) . "'";
}
$manipulation[$this->joinTable]['fields'][$this->localKey] = $itemID;
$manipulation[$this->joinTable]['fields'][$this->foreignKey] = $foreignID;
DB::manipulate($manipulation);
}
$manipulation[$this->joinTable]['fields'][$this->localKey] = $itemID;
$manipulation[$this->joinTable]['fields'][$this->foreignKey] = $this->foreignID;
DB::manipulate($manipulation);
}
/**

View File

@ -14,11 +14,21 @@ abstract class RelationList extends DataList {
* @param $id A single ID, or an array of IDs
*/
function setForeignID($id) {
// If already filtered on foreign ID, remove that first
if($this->foreignID !== null) {
$oldFilter = $this->foreignIDFilter();
try {
$this->dataQuery->removeFilterOn($oldFilter);
} catch(InvalidArgumentException $e) {}
}
// Turn a 1-element array into a simple value
if(is_array($id) && sizeof($id) == 1) $id = reset($id);
$this->foreignID = $id;
$this->dataQuery->where($this->foreignIDFilter());
return $this;
}
/**

View File

@ -3,7 +3,8 @@ DataObjectTest_Team:
Title: Team 1
team2:
Title: Team 2
team3:
Title: Team 3
DataObjectTest_Player:
captain1:
FirstName: Captain

View File

@ -33,7 +33,7 @@ class ManyManyListTest extends SapphireTest {
$compareTeams->byID($team1->ID);
$this->assertEquals($player1->Teams()->column('ID'),$compareTeams->column('ID'),"Adding single record as DataObject to many_many");
}
public function testRemovingSingleDataObjectByReference() {
$player1 = $this->objFromFixture('DataObjectTest_Player', 'player1');
$team1 = $this->objFromFixture('DataObjectTest_Team', 'team1');
@ -78,6 +78,20 @@ class ManyManyListTest extends SapphireTest {
$player1->Teams()->setByIdList(array($team2->ID));
$this->assertEquals(array($team2->ID), $player1->Teams()->column());
}
public function testAddingWithMultipleForeignKeys() {
$newPlayer = new DataObjectTest_Player();
$newPlayer->write();
$team1 = $this->objFromFixture('DataObjectTest_Team', 'team1');
$team2 = $this->objFromFixture('DataObjectTest_Team', 'team2');
$playersTeam1Team2 = DataList::create('DataObjectTest_Team')->relation('Players')->setForeignID(array($team1->ID, $team2->ID));
$playersTeam1Team2->add($newPlayer);
$this->assertEquals(
array($team1->ID, $team2->ID),
$newPlayer->Teams()->column('ID')
);
}
public function testSubtractOnAManyManyList() {
$allList = ManyManyList::create('DataObjectTest_Player', 'DataObjectTest_Team_Players','DataObjectTest_PlayerID', 'DataObjectTest_TeamID');