I've had exactly the same problem, filled it in issue
http://issues.ez.no/IssueView.php?Id=13170&activeItem=2
and had a similiar idea. :-)
Best regards,
Thomas Koch
Am Saturday 15 November 2008 11:15:55 schrieb Benjamin Eberlei:
> 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
--
Thomas Koch, Software Developer
http://www.koch.ro
--
Components mailing list
[email protected]
http://lists.ez.no/mailman/listinfo/components