Agenda Setting Using Hooks

'hooked' taken by Debbi LongAs I noted yesterday, using "public", "private",  "protected", and "final" in your class structures does a number of things for your code:

Most obviously to anyone who has ever done Object Oriented Programming, it sets some rules on who can do what with your classes.  But from another perspective, it's even more powerful than that.

Your usage of these keywords and how your other classes use them set an agenda and direction for your community.  They can provide clear examples of what is acceptable and how things should work.  In general, that's one of the most important things for an Open Source project or any other system that will ever be extended beyond the basic initial requirements.

Generally, they don't provide examples of what shouldn't be done… but – as a rule of thumb – if you're doing something unique from how the system normally works, you might ask yourself if "unique" is a good thing here.  But I digress…

A frequent request we see in the web2project space (and saw in dotProject before it) was the ability to wire actions to fire after certain events happen.  A common requirement might be "email notifications to all task assignees whenever the task is updated".  It's reasonable and there is code to handle it, but it tends to get complicated if other modules wish to perform the same action.  So what do we do?

After being a long-term Drupal user (4+ years now?), I decided it would be a hook system would be a reasonable starting point for a way to extend web2project and open the core to external developers and modules.  If you're not familiar with hooks, my friend and colleague Matthew Turland sums it up nicely on the Blue Parabola blog:

events originate from publishers, go through a handler, and are consumed by subscribers before being removed. You might also conceive that it's related to the Observer or Delegate design patterns or the callback and signals and slots programming constructs.

By moving these events – and the resulting actions – out to hooks that any other module can call, suddenly we've reduced the amount of custom coding and modification that has to be done on the core system.  More importantly, centralizing these calls allows us to practice the "Don't Repeat Yourself" (or DRY) principle and it's corrolary the "Keep your grubby paws out of the code you don't understand!" principle.

To date, there are two hooks implemented and room for many more:

The first is the cron_hook. It provides a simple way for every module to implement basic maintenance, cleanup, or scheduled tasks.  At present, only the Contacts module and one of my custom modules utilize it, but I have a few other places where it makes sense.  The best part is that any installed module (core or not!) can use it.  This has been available since svn revision 244 and is implemented by scheduling a crontask along the lines of:

wget -O – -q http://{web2project-install}/queuescanner.php;

The second is the calendar_hook.  It provides a simple way for every module to return a list of items relevant to a specific Users' calendar.  At present, this hook is used by Tasks, Events, and one of my custom modules, but it provides a simple iCalendar feed from the system.

Now that the first few are in place and available for usage, others will be developed over time.  I already have 3-4 spec'd out and ready for implementation.  I just need to get to it.  😉