Understanding Drupal8
Ivan Tsekhmistro
@ADYAX

The One with Questions
- What is the structure of Drupal 8?
- Symfony, Components ...?
- Service Container
- Event Subsribers
- Routing
- How it works?
The One with Past

The One with Warning
Things have changed...
get over it.
IN DRUPAL 8
The One with .... you know
Request

Repsonse

Magic!
how it works

Run...
Usually it's just some magic but...
The One with D8 Structure
Symfony 2 Components
- HttpFoundation
- DependencyInjection
- EventDispatcher
- Routing
+ D8 Components
+ DrupalKernel

+ Extended HTTPKernel
+ StackHTTPKernel

The One with DrupalKernel
DrupalKernelInterface
extends
HttpKernelInterface
- boot()
- shutdown()
- discoverServiceProviders()
- getServiceProviders()
- getContainer()
- ...
- handlePageCache()
- preHandle()
- handle()
The One with Service Container
Symfony uses a service container that can be used to efficiently manage services in the application.
This Service Container is a global object that is created and contained by the DrupalKernel before a request is handled. It can be used later in code to fetch services, lazy-loaded on the fly.
The One with Service Container configuration
services:
cache_factory:
class: Drupal\Core\Cache\CacheFactory
arguments: ['@settings']
calls:
- [setContainer, ['@service_container']]
...
http_kernel:
class: Drupal\Core\HttpKernel
arguments: ['@event_dispatcher', '@controller_resolver', '@request_stack']
parent: container.trait
language_manager:
class: Drupal\Core\Language\LanguageManager
arguments: ['@language.default']
language.default:
class: Drupal\Core\Language\LanguageDefault
arguments: ['%language.default_values%']
...
code snippet from `core.services.yml` file
Drupal's service configuration is based on YAML-files.
The One with Service Container compiled sample
/**
* Gets the 'http_kernel' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return Drupal\Core\HttpKernel A Drupal\Core\HttpKernel instance.
*/
protected function getHttpKernelService()
{
$this->services['http_kernel'] = $instance = new \Drupal\Core\HttpKernel(
$this->get('event_dispatcher'),
$this->get('controller_resolver'),
$this->get('request_stack')
);
$instance->setContainer($this);
return $instance;
}
/**
* service_container_prod
*
* This class has been auto-generated
* by the Symfony Dependency Injection Component.
*/
class service_container_prod extends \Drupal\Core\DependencyInjection\Container
{
public function __construct()
{
$this->parameters = $this->getDefaultParameters();
// ...
$this->methodMap = array(
'accept_header_matcher' => 'getAcceptHeaderMatcherService',
'access_arguments_resolver' => 'getAccessArgumentsResolverService',
'access_check.cron' => 'getAccessCheck_CronService',
'access_check.csrf' => 'getAccessCheck_CsrfService',
'access_check.custom' => 'getAccessCheck_CustomService',
// ...
'http_kernel' => 'getHttpKernelService',
///...
The One with Tagged Services
services:
access_check.permission:
class: Drupal\user\Access\PermissionAccessCheck
tags:
- { name: access_check, applies_to: _permission }
How does Drupal understand these tags and know what to do with them?
The One with Compiler Passes
/**
* Adds services tagged 'access_check' to the access_manager service.
*/
class RegisterAccessChecksPass implements CompilerPassInterface {
/**
* Implements CompilerPassInterface::process().
*
* Adds services tagged 'access_check' to the access_manager service.
*/
public function process(ContainerBuilder $container) {
// ...
}
}
In Drupal, there are some important compiler passes, such as the RegisterAccessChecksPass, which attempts to find all services tagged with access_check (see previous slide) and adds it to the AccessManager service.
The One with the Flow
- Set the class loader,
- Set the Drupal error handler.
- Read the settings.php file, and generate some other settings dynamically,
- Detect if Drupal is actually installed. If it is not, redirect to the installer script.
Create DrupalKernel from Request
Create the HTTP Request object (using Symfony HttpFoundation component)
Run StackHTTPKernel middleware stack ( aka stackphp )
- Handle Request via ReveseProxyMiddleware
- Handle Request via PageCache
- Handle Request via KernelPreHandle
Let DrupalKernel handle Request
boot() - load legacy includes, init Container, register streamwrappers, etc
of how the system works
The One with Kernel Events
When handle method of the DrupalKernel is called, it finally delegates the call to (Symfony2’s) HttpKernel, which further handles the request by dispatching Events step by step.
- kernel.request
- routing.route_dynamic
- routing.route_alter
- ...
- kernel.response
The One with Event Subscribers
Previously we have had a look at compiler passes. One particularly important usage of tagged services are the event_subscriber-tagged services.
Drupal's Subsrcibers for "kernel.request"
- AuthenticationSubscriber - Loads the session and sets the global user.
- PathSubscriber - Converts the url to a system path (url aliases, etc).
- MaintenanceModeSubscriber - If in maintenance mode, show the maintenance page.
- RouteProvider - Gets the a fully loaded router object.
- ...
The One with Router

Drupal 7
Drupal 8
Drupal 8 introduces a new mechanism for registering routes, implementing Symfony2's Routing component and the Symfony2 CMF Routing component extension.
Routes basically are the mappings between URL paths and their corresponding page and access callbacks.
The One left behind the scene
- Configuration
- Entities
- Plugins
- Drupal class
The One in summary
Developing our first Drupal 8 project was a real p... a lot of fun for our team.
Yes, I said fun. We enjoyed it, because it was our internal project and we were able to focus on learning the new stuff, contributing bugfixes, and developing best practices.
To be truly honest sometimes it was a real pain in the ass. Mainly because, some parts of D8 were "unstable".
But Future is coming.
Recommended links
- https://amsterdam2014.drupal.org/session/dependency-injection
- https://github.com/silexphp/Pimple
- https://cipix.nl/understanding-drupal-8-part-1-general-structure-framework
https://www.acquia.com/blog/ultimate-guide-drupal-8-episode-7-code-changes-drupal-8
http://www.sitepoint.com/drupal-8-hooks-symfony-event-dispatcher/
Thank you

Questions?
understanding-d8
By Ivan Tsekhmistro
understanding-d8
- 1,150