This is not documentation. This is literally the 30000ft high (I have written it on a Calgary-London flight) overview about Drupal 8 page flow as it stands on July 28, 2012. This doesn't mean it will be fully valid even a week later. Also, I am not writing out all the namespaces for classes, it's not necessary.

This is a fancy array of objects. The fanciness is mostly that the objects are only created when retrieved. When adding an object to the DIC we don't add an object but we specify how it will be created: either by specifying a classname and let the DIC call new $classname with it, perhaps with arguments. A fun feature that arguments can be other members of the DIC. Or we can specify a factory class and method. Or, instead of a factory class, we can use an object in the DIC as the factory. Very fancy. Examples from D8 core:

So this registers an object we will be able to retrieve with $this->get('resolver'). When the get() runs, it will create a new object of class Symfony\Component\HttpKernel\Controller\ControllerResolver.

So this registers an object we will be able to retrieve with $this->get('dispatcher'). When the get() runs, it will call the method
Drupal\Core\DependencyInjection\ContainerBuilder::getKernelEventDispatcher because that is set as a factory. As we have an argument here, it will be passed to the getKernelEventDispatcher() method. As it's a reference, that means it's something out of the DIC, in this case, the DIC itself. This DIC is called a service container and the thingies we put into the DIC are called services by Symfony.

* About the kernel

The HTTP kernel uses the event dispatcher to call the following events during handle():

The controller and the view might be skipped if during the request event an event subscriber happens to set a response already. That's mostly for redirects, access denied and such.

* About events

The events are somewhat like hooks just way, way more complicated. We register classes with the dispatcher which calls the getSubscribedEvents of that class which describes the methods to be called on events. Here's an example from the ViewSubscriber class:

then the onView method is called with the $event argument. All events get a single $event object which doesn't do much just has setters and getters.

The DIC examples above are from the constructor of Drupal\Core\DependencyInjection\ContainerBuilder and as you can see it creates
a dispatcher by calling the getKernelEventDispatcher which method creates an EventDispatcher object and adds a lot of event listeners. I will just point out the most important ones:

The LegacyUrlMatcher calls menu_get_item() for the current path (which was resolved by a listener I skipped).

$dispatcher->addSubscriber(new LegacyControllerSubscriber());

This will take the Drupal router item retrieved in the previous step and call the page callback / page arguments. More precisely, it sets the controller to a closure doing that. After the event, handle() calls the controller, this controller call itself is not an event. We have seen such things all the time in Drupal, a hook before doing something, very familiar.

$dispatcher->addSubscriber(new ViewSubscriber($negotiation));

This is the delivery callback. For example, for HTML requests it calls drupal_render_page().

So now we see what the Drupal 7 page workflow mutated into. And while this might change, knowing the kernel, the DIC, EventDispatcher will stay useful.

Great writeup, chx! And yes, conceptually most of that is not going to change drastically, since it's just "this is how Symfony does things".

The main thing that will change soon is the subscriber registration, as I *just* RTBCed the issue to use subscriber services for that. That means the addSubscriber() call will change, but the subscriber classes themselves will not. Also some of the subscribers will be changing around as we continue to refactor. (ViewSubscriber will likely change, and the Legacy* subscribers should go away eventually, etc.)

Very nice! Does this mean, however, that the traditional hook-based workflow will get replace by an event-driven one? Or will this change be more of a end-user transparent change in core and for modules defining hooks?

Do what I do: learn more. Don't let a challenge intimidate you to the point of closing yourself off completely. Learn to adapt (even something that may sound like a foreign language) and you will be a better developer because of it!

The Symfony flow is more abstract, so I can definately relate to folks who feel frustrated and abandoned by it. I also urge you to persist! The best way for me to learn is to step through a request in the debugger. If you never setup XDebug, you really ought to invest the effort. You can use PHPStorm or Netbeans or Komodo or Eclipse on the client side. It is a mind blowing experience to see a request wind its way to the browser. You can study it for hours and days and still stumble across interesting new twists.

Also, it seems that we are finally closing in on Drupal Pipes.

discailmre: Me no good type Egnlish fsat. yuo muts not cmplian ' bout the garmar. Site powered by Drupal 6