There are cases when in many to many relationships you need additional data that is only relevant, when in the context of the m:n relation but in neither object context alone. Currently this is not possible in ezcComponents.
I have looked at the ezcPersistentSession and relation related source code and came to the conclusion that is not an easy task to integrate without looking somewhat hackish. My first thought was to extend ezcPersistentSession::addRelatedOject to accept a new parameter with the additional data to be saved in the relation table via an relation data object. This is a very bad solution, since you now have the problem of how to retrieve the addtional data, and how their representations is defined and can be accessed. Then again, the data within m:n relation tables is only needed, when the relation is in full context, so i came up with a nicer solution that recognizes this relationsip: I would add a new ezcPersistentManyToManyDataRelation class that extends ezcPersistentManyToManyRelation. It has an additional property 'manyToManyClass', which is a representation of the aggregated data of destination and relation table. "manyToManyClass" has to full fill a a state aggregation interface ezcPersistentObjectAggregate, that has to functions getStates() and setStates() which return arrays of setState() and getState() of the related objects where keys are unique definition table names '$def->table'. Internally then all resolutions between the different tables can be resolved by iterating over the getStates() records and calling the appropriate means for each object state of the aggregate. A note: Technically the relation table with data has no definition and hence the definition manager will fail to locate it. Therefore many to many tables with data also have to have a definition file for this approach to work, also to define the fields that the relation table contains. A Definition has to exist for all the loader methods too. What information exactly this file should contain for my proposal to work i cant say for now, i'll have to build a prototype. Any ideas and/or comments? This is by far no issue i have thought to the end, so in questions of detail my proposal might utterly fail. :-) beberlei Attachment: Some Use cases of using my proposed relation: For a simple example in the ezcPersistentObject Tutorial context. Now 'persons_addresses' contains additional data on how long this person is already registered at this address: 1. definition $def->relations["Address"] = new ezcPersistentManyToManyDataRelation( "persons", "addresses", "persons_addresses" ); $def->relations["Address"]->columnMap = array( new ezcPersistentDoubleTableMap( "id", "person_id", "address_id", "id" ) ); $def->relations["Address"]->manyToManyClass = "PersonAddress"; 2. PersonAddress class PersonAddress implements ezcPersistentObjectAggregate { /** * @var Address */ private $address; /** * @var array */ private $persons_addresses; public function getStates() { return array( 'persons_addresses' => $this->persons_addresses, 'addresses' => $this->address->getState(); ); } public function setStates(array $states) { foreach($states AS $table => $state) { switch($state) { case 'addresses': $this->address = new Address(); $this->address->setState($state); break; case 'persons_addresses': $this->persons_addresses = $state; break; } } } public function setRegisterDate($date) { $this->persons_addresses['register_date'] = $date; } } 3 Use Case: $person = $session->load('Person', 1); $addresses = $person->getRelatedObjects(); foreach($addresses AS $address) { // now $address instanceof PersonAddress: $address->setRegisterDate(mktime(0, 0, 0, 5, 1, 2007)); // session recognizes aggregation interface, iterates over the states $session->update($address); } -- Benjamin Eberlei http://www.beberlei.de -- Components mailing list Components@lists.ez.no http://lists.ez.no/mailman/listinfo/components