Flourish PHP Unframework
This is an archived copy of the forum for reference purposes

Extending the ORM

posted by marcus 9 years ago

So this is an idea from Silverstripe which also has a ORM system.

Let's say I have a User class which extends fActiveRecord with the proper table set up in the database. Then if I wanted different kinds of users I would set up classes that extend User that in turn have tables set up with a one-to-one relationship to the users table via the primary key.

For example, let's say I have the tables users, company_users and private_users then I would create the classes User->fActiveRecord, CompanyUser->User, PrivateUser->User. Ideally Flourish would handle the joins behind the scenes and even though the two child classes consist of two tables it could be treated as one through the get/set methods.

I've actually managed to get a very basic version of this set up with Flourish today by overriding call() and sending along all methods to the child class which I store internally in the User class. This is of course not a really good, or I suspect, safe method so this kind of functionality would be awesome to have in Flourish.

I have no idea how big of a job it would be to implement this or even if it's the way you want to be doing things but I wanted to put it out there as an idea.

It should be possible to implement such functionality using the plugin architecture, in the same way as fORMCOlumn, fORMMoney, fORMOrdering, etc. You would basically need to reflect the parent object to get all of the applicable column-based method names, and proxy them. Then you'd have to implement custom load(), store(), validate(), etc that would call those methods on both objects.

This is how I would probably implement it, I just don't know when I'd be able to get to it. The only other thing to consider is issues where the two tables share column names. I imagine such databases would just not be supported.

posted by wbond 9 years ago

Ok so I have been trying out the plugin architecture with my current implementation in an effort to learn how all of this works and to see if I could make the functionality that I wrote in one class reusable as a plugin.

However when I read the code in fActiveRecord I realized that the call method matches the callback to the raw $method_name and not the $action. Would it be possible to check for both or would that slow things down too much?

What I'm after is the ability to override all calls to get/set not just specific calls to, for example getId.

posted by marcus 9 years ago

Scratch that I found the {prefix}* stuff. Awesome :)

posted by marcus 9 years ago

Ok so I'm pretty much finished with my rather weird implementation and overall everything worked great. The only thing lacking for me is a callback for post::loadFromIdentityMap(). If the following could be added to loadFromIdentityMap()

fORM::callHookCallbacks(
	$this,
	'post::loadFromIdentityMap()',
	$this->values,
	$this->old_values,
	$this->related_records,
	$this->cache,
	$object
);

It would give me a chance to modify the returned object. Right now the object that's returned is "bare bones" so to speak so if I've added my own properties to my fActiveRecord classes they won't get returned when loadFromIdentityMap() is used. With this callback I would get the chance to make those modifications. I've tried adding it and it works.

posted by marcus 9 years ago