More on possible Events in CakePHP
As a follow up to: Events in CakePHP – I really like it
Let’s say you have unkown entities in your project – totally dynamic. Let it be a plugin, another model, not associated at all. Getting new functionality into an existing app can be a pain.
Events do help alot in this case, depending on how you layed out the triggers. Events notify all possible candidates (”can u handle?”) every time something interesting is happening, like “user logged in”, “new image was uploaded”, “post has been edited by xyz”, and so forth.
In this post i want to explain more about the benefits and how events could make your life alot easier in the long run.
Some example
Think of a users dashboard: A dashboard usually has alot of links to various aspects of the application, often categorized in blocks. You have a block for the user account itself, a block for the latest comments, a block to upload a new image, etc..
Now maybe user XYZ has access to post blogs, but maybe not. And maybe there is no blogging function at all. We could now bake our blogging MVC and write it into the dashboard action. No problem, right? But the more you add, you more have to maintain and watch out for. I know many projects with complicated group setups and stuff so this isn’t always that simple.
This is where Events come in handy. Let’s scratch the above and think our dashboard action is empty and there’s a single call to the EventDispatcher (the thing i use). If we now simply fire a “dashboardView” event any part of the codebase that can handle this event will perform its designated task independently.
function dashboard() {
$data = $this->Events->dispatch('dashboardView', array(
'user_id' => $this->Auth->user('id')
));
$this->set('data', $data);
}
This allows the blog-facility (for example) to run code and add data to the dashboard() action, so that the action itself remains clean.
Normally you would load up some settings array with true/false, or you would just add a if/else in the dashboard() action.
function dashboard() {
if ($mayAuthorBlog) ..
if ($mayPostNews) ..
if ($justRegistered) ..
...
}
All this is not necessary when using events, since events usually don’t care if they are handled. They are just fired and poke around and execute whatever responds.
With “poking-around” i mean that you may have multiple handlers for a single event. So the Post, Image, Blog, Friend MVC .. all of them can respond to the current action. Even if they are out of scope.
The other way around
If we decide to drop any functionality later on, we just delete the event-listener, or delete the method that usually would respond. A common task may be: “The blogging dashboard item should not be intergrated into the dashboard anymore”. Remove the listener from your Blog-MVC and you’re done. Not touching the working dashboard() action at all.
See, if we wrote this without Events the removal of this functionality would require that we delete the if/else (or what have you) from the dashboard() action, which is destructive and eventually leads to bugs and headaches. Removal of event-listeners don’t harm your app.
…for the non believers
One can argue: “Why not simply add a private method for that?”
Well.. the keyword is “unkown”. Events enrich a function by providing an open interface to hook up to (so to speak). If you wrote something new you just provide the listener for your current/core app and be done with it.
class UserControllerEvents extends AppControllerEvents {
var $name = 'UserController';
function onDashboardView($event) {
$event->Controller->User->logVisit($event->user_id);
}
}
class BlogControllerEvents extends AppControllerEvents {
var $name = 'BlogController';
function onDashboardView($event) {
return $event->Controller->Blog->getMostRecent();
}
}
Private Methods or “helping” methods are bound to the main codebase and scope and as such quickly become obsolete or hard to manage. It’s also not so easy to call other parts of your cake app “just like that”. The system described works as one huge layer and has access to everything.
What do you think?
Let me know in the comments.


Looks really interesting.
This type of functionality would be really big for any application that uses a lot of plugins.
To get some simple events going I currently use AppController and requestAction. All “events” are defined as actions in AppController, returning false. Any plugin that wants to catch an event overrides the action. Dispatching of these events is done by lopping through the installed plugins and calling the event-action on each plugin’s “root” controller.
It is clunky but for cron jobs (on_hourly_update) and the few events (on_incoming_mms) I need to dispatch it works ok. But a “real” event system would be really cool. Could be the best thing since Containable… almost :)
Let me know if any help is needed coding, testing, documenting or anything… I’d love to do what little I can.
Hi Martin,
thanks for your comment. When i get the time this weekend i’ll setup a little repo for this.
Current layout is close to cake default layout and does not mess with the core:
Looks pretty portable so far, but i’ll try to make it more transparent. Oh.. and it’s PHP5.
http://github.com/m3nt0r/eventful-cakephp/
Hi Kjell,
Did you run any benchmarks? What happens when you have 10 controllers to search for hooks? 50? 100?