We could use stdClass to create any kind of objects. But objects are always passed as reference. This is good for the memory but dangerous for the application code. If passed by reference a plugin can (accidentally) change data in the argument object. Arrays are passed by value (but only copied on change). If a plugin changes some argument values it does not affect the original data. The plugin has to return the new data and even then the application can decide whether to use the changed data or not. With
arrays
we can have "read-only" arguments, with objects we don't.
The arrays aren't really read-only because the plugin can write on them. This could be a stumbling block for plugin development because the developer doesn't see the variable is read-only.
We can have read only arguments with classes. class foo { private $bar_ro; private $bar_rw;
public function getBar_ro()
{
return $bar_ro;
}
public function getBar_rw()
{
return $bar_rw;
}
public function setBar_rw($value)
{
//check some things here
if($value < 0)
throw new Exception('setBar_rw bust be equal or more than 0')
return true;
}
} There is no setter so a plugin which gets this class parameter could not set $bar_ro - but read it. The variable $bar_rw could be written also - but there are some checks if the values are correct. We can also control & check given data so we could write it back if the core code without any problems.
We just have to define data classes we can use in our plugins. Maybe we find a way to isolate plugins to these functions (and not to access roundcube objects directly e.g. using the main roundcube singleton (cannot remember the name right now)? Don't know.
I think we have three types of hooks: (+ two special types)
Hooks should always get one argument (could be null) which is an array.
In
case of the address book we have the rcube_result_set class which is some sort of an iterator for "data rows" or records.
Ok, than any hook should send them array(foo), where foo is a data class.
After calling a hook we should take the returning object and write it
back
to the original sources, right?
It depends on the implementation. The core application should have
control
of what data can be changed by a plugin and not the plugin itself.
Agree. With the above code (classes rather than arrays) we can delegate some data checking logic to the plugin-architecture.
Ah... btw: I prefer the naming convention 'user-login-after' instead of your 'after-login' for hook names because it groups things together. I havn't seen rules on this in the guidelines, is there any? It just groups together what should be togehter. Any hook on user begin with..: user Any hook on login begins with: user_login The hook after a login uses..: user_login_after Is this OK? (I chaged the dash with underline too meet the guidelines)
That's OK. Since hooks are not directly related to object methods but simple strings we're not bound to the guidelines here. Using dashes could help distinguish between hooks and method names...
Ok, let's use dashes.
I think this is the clearest definition we had so far. What do you think?