private function preDispatch($eventName, Event $event) {
// wrap all listeners before they are called
$this->wrappedListeners[$this->id] = new \SplObjectStorage();
$listeners = $this->dispatcher
->getListeners($eventName);
foreach ($listeners as $listener) {
$this->dispatcher
->removeListener($eventName, $listener);
$wrapped = $this
->wrapListener($eventName, $listener);
$this->wrappedListeners[$this->id][$wrapped] = $listener;
$this->dispatcher
->addListener($eventName, $wrapped);
}
switch ($eventName) {
case KernelEvents::REQUEST:
$this->stopwatch
->openSection();
break;
case KernelEvents::VIEW:
case KernelEvents::RESPONSE:
// stop only if a controller has been executed
if ($this->stopwatch
->isStarted('controller')) {
$this->stopwatch
->stop('controller');
}
break;
case KernelEvents::TERMINATE:
$token = $event
->getResponse()->headers
->get('X-Debug-Token');
// There is a very special case when using builtin AppCache class as kernel wrapper, in the case
// of an ESI request leading to a `stale` response [B] inside a `fresh` cached response [A].
// In this case, `$token` contains the [B] debug token, but the open `stopwatch` section ID
// is equal to the [A] debug token. Trying to reopen section with the [B] token throws an exception
// which must be caught.
try {
$this->stopwatch
->openSection($token);
} catch (\LogicException $e) {
}
break;
}
}