Destroy every zig! The official Gerry Vandermaesen blog

20Apr/111

Relaying Doctrine events to symfony

If you need to relay your Doctrine events to symfony, you might get tempted to create a dependency to sfContext in your models. As we all know (right?) this is a path straight down to hell.

One might argue that triggering symfony events should be done in the controller only, but if you want to hook too many different record events for example, it's quite cumbersome to do this in every controller where you perform a certain (let's say "update") action on a model, and it is not very DRY.

A solution I used in a recent project was creating a small container for my symfony event dispatcher, think of it as a mini-DIC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
 
class myEventDispatcherContainer {
 
  protected static $dispatcher;
 
  public static function setDispatcher(sfEventDispatcher $dispatcher) {
    self::$dispatcher = $dispatcher;
  }
 
  public static function getDispatcher() {
    if (is_null(self::$dispatcher)) {
      self::$dispatcher = new sfEventDispatcher();
    }
    return self::$dispatcher;
  }
 
}

Now, we have to make sure that in our symfony context, we are setting the right dispatcher on the container. We can do that in our application configuration.

1
2
3
4
5
6
7
8
9
10
<?php
 
class frontendConfiguration extends sfApplicationConfiguration {
 
  public function initialize() {
    myEventDispatcherContainer::setDispatcher($this->dispatcher);
    // other stuff...
  }
 
}

Now in our models we can "safely" trigger symfony events, for example:

1
2
3
4
5
6
7
8
9
<?php
 
class Foo extends BaseFoo {
 
  public function preInsert($event) {
    myEventDispatcherContainer::getDispatcher()->notify(new sfEvent($this, 'pre_insert'));
  }
 
}
Comments (1) Trackbacks (0)
  1. Nice!
    But then you should do this in every model.. not so DRY.. is it?
    Is there any tweak you can do to relay them from just one point in the app?
    and to enable it for DQL also? not just records…
    Cheers!


Leave a comment

(required)

No trackbacks yet.