At Tycoon Research we have a significant investment in both Code Igniter and Ruby on Rails. Frequently the differences in methodologies between the two is striking.

We ended up writing quite a few libraries to make CI less painful to develop with while fitting into the CI way of doing things. The CI-Events library is one of those libraries.

Why do you need an event library?

We were running into situations where several parts of our system needed to deal with certain things happening such as user registration.

In that case we were ending up with a Users#create method calling out to many, many other models and libraries or, even worse, handling things unrelated to a User. Over time this can get quite sloppy, bug ridden and difficult to maintain.

An event library allowed for proper separation of concerns resulting in simpler, easier to read code.

Why CI-Events?

We had four main goals:

  • Don’t introduce a lot of additional overhead.
  • Flexible enough to handle multiple usage styles.
  • Fit well into the CodeIgniter way of doing things.
  • Considering the indirection involved, attempt to keep things readable.

Admittedly, two of the four are subjective but, with the criteria in mind the other event libraries we looked at failed on one of more of these points. Most significantly, there was no single way of knowing what events were handled by what code.

Another, more minor issue, was the introduction of a new kind of handler file into CI. We felt that was unnecessary.

Usage

The library stores it’s event configuration in a configuration file: config/events.php. The empty config/events.php in the repo contains detailed documentation but, here’s some examples:

For each event there’s an array of handlers. A handler consists of the CI object type, the name of the object, the name of the method and an optional forth argument that may be anything you like.

This approach gives you a few things:

  • One point of reference for all the events in your system.
  • Delegation of event handling to existing libraries and models where appropriate.
  • Reuse of a single handler by modifying the handler’s behavior based on the forth argument.

Sending events is very simple:

The first argument is simply the matching event from your config/events.php. The second argument, like the forth argument in the config file, is entirely optional and may be whatever you’d like it to be. We’ve largely stuck to passing associative arrays through the second argument and been very happy with the result.

Finally, the actual handler:

It’s important to note that all three arguments are optional on the handler methods. If you accept no arguments, it’ll call your method without any arguments. Accept one and you’ll get just the second argument passed to the ->send call. The second argument, when present, will receive the forth argument from the config file. The third and final argument will be the name of the event such as profile.created.

This library has served us very well, in production, for a few months now. Feel free to use it and contribute back if you feel it’s missing something.

Update

I’ve pushed a very simple demonstration application to github. You can find it at http://github.com/rich/ci-events-demo-app. The handler library is simply called Thing and you can see it in system/application/libraries/Thing.php. The event is sent by the default welcome controller. The output looks like this:

5 Responses to “CI-Events: A Code Igniter event library”

  1. Miami_coder Says:

    Hi Rich/Tycoon,

    Thanks for your contribution to CI. You set a great example for other companies to follow.

    Second, I'm not sure I understand well how to pass those named args to your function assign_points, would you have a more detailed/basic example?

    Sorry for just not getting it.

  2. Colin Says:

    I don't see why you should need to configure each event. Seems like a convention would make more sense, so you hook into an event automatically instead of explicitly having to configure it. CI hooks already provides this, really.

  3. Rich Cavanaugh Says:

    @Miami_coder

    The arguments actually get passed automatically by the library. This happens when you send an event that method handles.

    I'll see if I can get an example app up on github in a day or two.

    @Colin

    It's not so much as you're configuring the event as the handlers. There would be no way to do the handler just by convention since the library containing the handler may not even be loaded when the event is triggered.

    CI Hooks do provide a small portion of the functionality that our library provides. It's missing the various argument passing mechanisms though which are pretty critical to our use cases.

  4. David Says:

    I took a stab at this today and the library threw a couple nasty exceptions and I'm not really sure what I did wrong.

    I set up the config file with a simple item that looks like this:

    $config['item.logged'] = array( array('library', 'Foo', 'log_item') );

    Then in my controller I sent the event like was mentioned:

    $this->events->send('item.logged', array('item' => 'Test item'));

    From that though, I get a fatal error with the message "Uncaught exception 'ReflectionException' with message 'The parameter class is expected to be either a string or an object'". Any ideas what I'm doing wrong here?

  5. Rich Cavanaugh Says:

    @David

    The library doesn't really do any sanity checking of the config/events.php file. Basically, the library names need to be all lower case. So, where you have "Foo" it should be "foo."

    Also, I've updated the post to link to a new repo on github. It's a demonstration CI application including the events library.

Leave a Reply