EllisLab text mark
Advanced Search
     
Plugin Architecture: Hooks and Callbacks
Posted: 26 December 2007 12:22 PM
Avatar
Joined: 2007-12-23
3 posts

Having recently joined CI, I brought up a topic in the Introduce Yourself area that is better served here…

The Need

PROBLEM: When designing an application, one doesn’t know how the application will evolve, what features it will grow into, how many ways it will present itself, etc.  How can one not only mitigate risk, but also enhance the application’s ability to be successful given the lack of foresight?

SOLUTION: Design for extensibility.  One technique is to carefully consider the core logic and write it, placing hooks at those places where one might either extend or replace something.

For any application that is being developed, careful consideration will reveal the core logic for that application.  The core logic is a small kernel of code in which the fundamental code has hooks that implement initially-conceived functionality.  Callbacks are registered for these hooks for the first version of the application.

Invariably, during the development process, those functions need to be expanded or replaced.  Each of the defined callback functions themselves can define hooks themselves.  This allows core, 3rd-party, and modifications to 3rd-party extensibility to take place since each can define hooks and register callbacks.

What Others are Doing

There are a number of frameworks that do this kind of thing:

* MediaWiki Hooks
* WordPress Plugin Hooks
* SquirrelMail Plugins
* Cacti Plugins
* Smarty Plugins
* PHPClasses: PHP Callback

In designing a plugin architecture, there are a number of things to consider:

* hook/callback architecture - deciding on how it works.
* static plugins - plugins live on the server as part of core/generally-available plugin sets available to all users.
* user plugins - plugins that are available to only specific users.
* plugin loading - are plugins loaded: always, never, or only when needed?  Can they be unloaded?
* plugin installation - is there an API for plugin installation?  This can be used by system administrators or provide functionality so that users can upload their own plugins.
* web services - are plugins exposed as web services APIs?  Are these authenticated?  This allows the functionality of the application to be not limited to just one website… it or parts of it can be embedded in other websites.

Why is it Worth Doing?

A Plugin Architecture, implemented as Hooks with registered Callbacks, enables an application developer to mitigate risk due to unforeseen features, allows the writing of cleaner code, makes 3rd-party plugin development an automatic opportunity, makes documentation more compartmental, reduces QE costs because the code is significantly more modular, makes it easier to have a larger team of developers since they’re able to work independently, and makes Web Services APIs easier to implement and maintain.

So, since many of the applications we build are built with a plugin architecture, and since we’re now looking to add CodeIgniter to our development framework for many of the same reasons, I’m wondering:

* What would be involved in modifying CI’s hook code to become a separate class that can serve not only CI’s needs, but also allow developers to use it for their own code?
* What, if anything, has been done already?
* How do we work with CI’s developers on this?  If this is something that has not yet been done, since we’re going to do something, we might as well help out the CI community.

Happy Holidays!

 
Posted: 26 December 2007 01:51 PM   [ # 1 ]   [ Rating: 0 ]
Avatar
Joined: 2007-02-21
273 posts

There’s a related discussion here.

 
Posted: 26 December 2007 02:07 PM   [ # 2 ]   [ Rating: 0 ]
Avatar
Joined: 2007-02-21
273 posts

When I saw your extensivity thing, I first thought about a simple Vanilla-like delegation.
My idea is quite simple, but maybe too simple for you.

Using a very early hook, we discover plugins in a special (and of course configurable) directory. Those plugins are simple callbacks declarations and registrations, that we ‘include’.

// in the plugins files: the injected code
function my_function()
{
$var 
&= $ci->plugin_lib->param('param_id');
// some processing
}
$ci
->plugin_lib->register('my_function''moment_id'); 
// anywhere else: where we want to inject some code
$ci->plugin_lib->add_param('param_id'$the_param);
$ci->plugin_lib->moment('moment_id'); 

The ‘moment’ function then calls every function that has registered to act at the ‘moment_id’ moment.

About the name, CI has (had) already a ‘plugin’ thing. Vanilla calls this ‘delegation’, if I were the boss, I’d call this ‘injections’.

 
Posted: 05 August 2008 06:09 PM   [ # 3 ]   [ Rating: 0 ]
Avatar
Joined: 2008-07-16
411 posts

That is a perfect sum-up fatbear. 5 stars!

In a more recent conversation Colin and I talked about a way to implement something like this. Right now most systems enable the call from the code:

//Add a plugin call to myfunction()
$plugin->add('hook_name''myfunction'); 

Then when the system gets to “hook_name” and runs it - it calls “myfunction” and passes it some data to modify or something. That is how wordpress and others give 3 partys the ability to change/add to the existing code. They auto-load all plugins on startup(like read_dir) and when each plugin is loaded it runs the above code to add itself to the plugin registry so that it gets called.

I think that rather than embedding the hook/pluginname into the code of each plugin (and then auto-loading all plugins on startup) we should use a config file for a CI version (just like the way “hooks” are used in CI).

This not only makes it easier to remove calls to certain plugins - but what if someone else comes along and wants to use another plugins call within a plugin.

Just change the config file.

So I was thinking about extending the “hooks” class to allow other plugins (from now on called “hooks”) to be loaded and called when needed. The current hooks class only has 8 places to call from and locks the developer out of creating more hook-on places.

$hook['myhook'][] = array(
                    
'function' => 'render_layout',
                    
'filename' => 'render_layout.php',
                    
'filepath' => 'hooks'
                    
//'class'    => 'layout',
                    //'params'   => array('red', 'yellow', 'blue')
); 

I am going to start extending the core hooks class as I think that is the best way to leech on to the existing “hooks” stuff without changing the way others are used to using CI.

Note: All this was a call for help smile

 Signature 

My Blog, C2D, PHP Videos, Résumé, Super .htaccess, Extra hooks, and MicroMVC

 
Posted: 05 August 2008 07:40 PM   [ # 4 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

I do have something like this in development. With only two methods in a Library, it’s already really effective. It is something I consider releasing soon. One thing I come up against is that I would want to provide a very low-level tool. Anybody using it would have to implement it into the MVC pattern in the best way they see fit, becuase I don’t want to introduce new conventions for all users (although I certainly have in the app where I am using it)

About the name, CI has (had) already a ‘plugin’ thing.

They have long since been removed though. I would consider it available. I have had trouble putting a name to it though. Hooks seems best to me, but CIs already defined Hooks in their own way.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
Posted: 05 August 2008 09:17 PM   [ # 5 ]   [ Rating: 0 ]
Avatar
Joined: 2008-07-16
411 posts
Colin Williams - 05 August 2008 11:40 PM

I do have something like this in development. With only two methods in a Library, it’s already really effective. It is something I consider releasing soon.

I released mine - Check it out and see if your’s is better
code.google.com/p/codeigniter-extrahooks/

One thing I come up against is that I would want to provide a very low-level tool. Anybody using it would have to implement it into the MVC pattern in the best way they see fit, becuase I don’t want to introduce new conventions for all users (although I certainly have in the app where I am using it)

Yes, this extended “hooks” class does not interfere with a users choice of how to use it - or with the default use of hooks in the CI core.

This class supports classes and functions just like the first one.

 Signature 

My Blog, C2D, PHP Videos, Résumé, Super .htaccess, Extra hooks, and MicroMVC

 
Posted: 05 August 2008 09:39 PM   [ # 6 ]   [ Rating: 0 ]
Avatar
Joined: 2007-06-10
2937 posts

Neophytes khaos events library allows using hooks to load plugins. Check it out.

 Signature 

URI Language Identifier | Modular Extensions - HMVC | View Object | Widget plugin | Access Control library

 
Posted: 05 August 2008 10:10 PM   [ # 7 ]   [ Rating: 0 ]
Avatar
Joined: 2008-07-16
411 posts
wiredesignz - 06 August 2008 01:39 AM

Neophytes khaos events library allows using hooks to load plugins. Check it out.

Thanks for pointing that out - His lib is pretty impressive. However, it seems a little overkill..? Maybe mine is to simple wink


He states

I wish to log a user in so i do my usual login code and now i want to give other applications a chance to login using the same credentials say phpbb so i invoke $this->hooks->_call_hook(’user_login’); and thats where i get stuck, how would you pass the user credentials as the params are fixed in the config/hooks.php config file for each hook, as best as i can see anyway. Assuming this wasnt a problem i’d want to see how each of the scripts phpbb etc responded and if any failed maybe abort the login or log a message though just scanning the code the return data doesnt appear to be captured or returned when you call a hook.

Which is exactly the gap my class fills - so I am trying to figure out where his script is better than mine now…

 Signature 

My Blog, C2D, PHP Videos, Résumé, Super .htaccess, Extra hooks, and MicroMVC

 
Posted: 05 August 2008 10:20 PM   [ # 8 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

Check it out and see if your’s is better

Well, there’s not much to check out. No docs, no usage examples, and I’m not about to pour through the code and assume what I can do with it, exactly.

I actually think my idea takes quite a different route. But it’s hard to say without seeming some implementation examples.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
Posted: 05 August 2008 10:37 PM   [ # 9 ]   [ Rating: 0 ]
Avatar
Joined: 2008-07-16
411 posts
Colin Williams - 06 August 2008 02:20 AM

Well, there’s not much to check out.

Yep, that’s how simple it is. If you understand CI hooks - then this is just CI hooks you can use in your own controllers.  cheese

 Signature 

My Blog, C2D, PHP Videos, Résumé, Super .htaccess, Extra hooks, and MicroMVC

 
Posted: 05 August 2008 10:43 PM   [ # 10 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

Heh.. I got my answer in your other thread smile

I think it’s a really nice extension of CI’s Hook system. Whether or not that’s what I think is needed is another thing altogether…

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
Posted: 27 October 2008 03:52 PM   [ # 11 ]   [ Rating: 0 ]
Joined: 2008-07-13
45 posts

I would really like a feature like this. I am also a Drupal developer so I am aware of how useful a hook system is. smile

Edit: To clarify, I do not develop Drupal’s core. I have used Drupal to make websites.

 
Posted: 27 October 2008 04:33 PM   [ # 12 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

Actually, what I am (was) working on, vendiddy, was based on Drupal’s hook system. PM if you want the code.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
Posted: 11 September 2012 05:04 PM   [ # 13 ]   [ Rating: 0 ]
Joined: 2012-09-11
1 posts

I just wanted to throw Magento in here as a good example of extensibility, I know it might seem too complex at first, but it’s actually a very well thought out modular architecture.

It employs an event driven architecture, which is a take on the hook/callback architecture mention in the OP. Callback (observer) methods are paired to events (hooks) via XML config files in each module’s directory, which are parsed (and cached) by the Core. This is similar to CI’s implementation, but even more flexible, as it allows all modules to create events, they aren’t limited to core hooks.