Hi,
- $this->prop['plugin_dir'] = $this->prop['plugin_dir'] ?
unslashify($this->prop['temp_dir']) : INSTALL_PATH . 'plugins';
- $this->prop['plugin_dir'] = $this->prop['plugin_dir'] ?
unslashify($this->prop['plugin_dir']) : INSTALL_PATH . 'plugins';
yes - this is defnitly against the 80-char lines rule if I write it in one line. I've just done copy&paste here - sorry. There are some other issues in my code which I will come after.
- The plugin class, once instantiated, should register it's
hooks at the plugins repository (rcube_plugins class). No implicit calling of an object method. Otherwise hook names are restricted to naming conventions.
After careful thinking - yes there are some ideas in background why I coded it this way.
registration. Now I thought again and there could be an issue without registering: It could be a big performance issue if we try to call any hook on any plugin. So we have to register hooks. 2. if you know the name of the hook you know when it is called, so you can understand 3rd party plugins faster. But with a hook registry you have one single place to look at (constructor of the plugin) so this shouldn't be an issue.
- Same as in 1) for the rcube_plugins class. The application
should trigger a plugin-hook by calling one single method (like 'trigger_hook()') and pass the name of the hook as the first argument.
Yes. I agree. I first thought of an included API to help plugin developers this way - but I now think this does not make sence. This is just too much overhead if we get many hooks (and I think we will get really many hooks!)
- Hooks need data and (maybe) return modified data.
Therefore I suggest to pack all data of a plugin-hook into a single argument which is an array (or object). The plugin method then returns the complete array (object) with modified data. Triggering a hook would then look like this:
$credentials = $plugins->trigger_hook('before-login', array('user' => $user, 'pass' => $pwd));
Yes, some hooks may need data. I personally prefer objects rather than arrays. I dont know if there is an object for any kind of data. If not we have to write them too. I think we have three types of hooks: (+ two special types)
be gathered from the session vars. But it does make sence to give the user data directly to the hook - if we change the way RC saves userdata we do not have to change the plugins, so this type should likely be non-existent. 2. hook with one "data row", like editing a contact: here the hook should get an object with the data. 2.1. special hook with one "data row" from different sources. For example the hook 'addressbook_contact_edit' which could need data from the user object and from the contact object 3. hook with multiple "data rows", like deleting multiple contacts at once. Shall we give an array of objects to the plugin or shall we call the hook with each data row? (Excuse me about talking in data rows - it's just easier to understand even if it's not 100% the right word for it) 3.1. special hook with multiple "data rows" and objects from different sources. 'addressbook_contact_delete'
How should we handle different types of hooks? I think we shall not use 1. (see reason above) The 2nd one is easy and most used. For the 3rd we have multiple options:
registry. For some plugins it could be essential to handle all hooks at once. For the special cases 2.1. and 3.1. we could again use an array() including all objects (or array of objects) Some code to show this cases: Case 1: no code because we shouldn't use it. Case 2: 1 data row, 1 data object $data_object = $plugins->trigger_hook('foo', $data_object); Case 2.1.: multiple data rows, 1 data object $array_of_data_objects = $plugins->trigger_hook('foo', array($data_object_1, $data_object_2)); If the plugin registered with the option to get single data rows the rcube_plugins class could handle to split it and reassemble it before/after calling the function as in 2. Case 3: single data row with data from more objects $array_of_data_objects = $plugins->trigger_hook('foo_user_and_contact', array($user_object, $contact_object)); Case 3.1.: multiple kinds of objects each and multiple data rows $array_of_data_objects = $plugins->trigger_hook('foo_user_and_multiple_contacts', array($user_object, array($contact_object_1, $contact_object_2))); Same as in 2.1. these array could be splitted in multiple calls like in 3.
Uh, gets complicated now. Is there an easier way? Don't think so, but im tired ;-)
After calling a hook we should take the returning object and write it back to the original sources, right?
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)
- Please read the http://trac.roundcube.net/wiki/Dev_Guidelines,
especially the naming conventions.
Thanks.
We also have a wiki on http://trac.roundcube.net. Feel free to create pages and upload patches there.
I'm just used to my site and want to be able to make backups, ... Thanks anyway. I'll note the requests here on my site http://www.lagg.at/temp/todo-rc-plugin
Thanks for your work so far! Thomas
Thanks for your work so far! I use it - so I can also give something.
I want to point you again to this site: http://www.lagg.at/temp/todo-rc-plugin We have to decide which hooks we need right now. I have added all hooks which I eventually ever need for my funambol-plugin. If you have no special wishes for hooks right now I will implement these only at first. This will be the better approach than implementing all possible hooks and never use them.