D8: App life cycle 

Routing

Events

The Story of one brave user's Request

App life cycle

-> Server

Client -> 

Request

Response

http_foundation

http_kernel 

flow process

-> Server

App

flow objects

Drupal core

Bootstrap +

TODO:
add xmind map

flow process

flow objects: ontology

Route

Controller

View

Request

Response

Request

GET /search?s=Drupal+8 HTTP/1.1
Host: dru.io
User-Agent: Mozilla/5.0 (Macintosh)
Accept: text/html,application/xhtml+xml
Referer: http://dru.io/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
...
$_SERVER['HTTP_ACCEPT']
$_SERVER['HTTP_HOST']
$_SERVER['HTTP_REFERER']
$_SERVER['REMOTE_ADDR']
$_SERVER['REMOTE_HOST']
$_SERVER['REMOTE_PORT']
$_SERVER['SCRIPT_URI']
$_REQUEST['...']
$_POST['...']
$_GET['...']
...
$request = Request::createFromGlobals();

\Symfony\Component\HttpFoundation\Request {
  ...
  public function initialize(...)  {
    $this->request = new ParameterBag($request);
    $this->query = new ParameterBag($query);
    $this->attributes = new ParameterBag($attributes);
    $this->cookies = new ParameterBag($cookies);
    $this->files = new FileBag($files);
    $this->server = new ServerBag($server);
    $this->headers = new HeaderBag(
      $this->server->getHeaders()
    );
    ...
  }
  ...
}

$request->get('host');
$request->getHost();

In HTTP

In PHP

In Symfony

flow objects: ontology

Response

flow objects: ontology

Response

flow objects: ontology

HTTP/1.1 200 OK
Server: nginx
Date: Tue, 06 Feb 2018 15:21:49 GMT
Content-Type: text/html; charset=utf-8
Keep-Alive: timeout=60
X-Drupal-Cache: HIT
Content-Encoding: gzip
Transfer-Encoding: chunked
...
<!DOCTYPE html>
...
public function send() {
  $this->sendHeaders();
  $this->sendContent();
  ...
}
HTTP/1.1 200 OK
Cache-Control: must-revalidate, no-cache, private
Content-Encoding: gzip
Content-Language: en
Content-Type: application/json
Vary: Accept-Encoding
X-Drupal-Ajax-Token: 1
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
Content-Length: 1822
...

{"command":"settings","settings":{"ajaxPageState"...
...

AjaxResponse

HtmlResponse

View

flow objects: ontology

format = ‘html’
format = ‘dialog’
format = ‘modal’
format = ‘ajax’

-> sets response content

-> render content

HtmlRenderer

Routing

http_kernel 

flow process

RouteBuilder

Routing

-> RouteProvider

    ->Routes

Router

-> RouteProvider

  -> Routes

 

-> findRoute

  -> Route   

    -> Controller

collect

execute

Router

getInitialRouteCollection

applyRouteFilters

matchCollection

applyRouteEnhancers

getRoutesByPath

filter by format, method, content type, etc..

compile Route,
check path conditions by preg_match

load parameters

checkAccess

check access for loaded parameter

defines how requests are handled within your application.

Route definition:

  • machine name
  • url serving pattern
  • handler
  • requirements
  • options

urls are case insensitive, ~8.3 https://www.drupal.org/node/2852554

Route

= pattern + handler

/hc/issue/{issue_id}/edit
\Drupal\hc_issue\Form\IssueEditForm

controller, form, resource

route

types

 

  1. Literal segments.
    /admin/content
  2. Route parameters with constraints.
    /node/add/{node_type}, /node/add/{node}
  3. Route parameters without constraints.
    /file/progress/{key}
  4. Wildcard parameters segments with constraints.
    No support
  5. Wildcard parameter segments without constraints.
    No support, workaround https://drupal.stackexchange.com/a/220730/5501

route

definitions

static

*.routing.yml

dynamic

routing.route_dynamic event

programmatic

*.routing.yml

route_callbacks:
  - 'views.route_subscriber:routes'
core/modules/node/node.routing.yml
hc_issue.view:
  path: '/hc/issue/{issue_id}'
  defaults:
    _controller: '\Drupal\hc_issue\Controller\IssueController::view'
    _title: 'View'
  requirements:
    _permission: 'access content'
Drupal\Core\EventSubscriber\EntityRouteProviderSubscriber
core/modules/views/views.routing.yml

altering

routing.route_alter

Drupal\Core\EventSubscriber\EntityRouteProviderSubscriber

YML

CLASS

define

alter

Routing elsewhere

ASP.NET

Ruby on rails

/var/www/html$ drupal dev kernel.request
 ---------------------------------------------------------------------- -----------------------------------
  Class                                                                  Method
 ---------------------------------------------------------------------- -----------------------------------
  Drupal\Core\EventSubscriber\OptionsRequestSubscriber                   onRequest: 1000
  Drupal\Core\EventSubscriber\RedirectLeadingSlashesSubscriber           redirect: 1000
  Drupal\Core\EventSubscriber\AuthenticationSubscriber                   onKernelRequestAuthenticate: 300
  Drupal\devel\EventSubscriber\ErrorHandlerSubscriber                    registerErrorHandler: 256
  Drupal\devel\EventSubscriber\ThemeInfoRebuildSubscriber                rebuildThemeInfo: 256
  Drupal\Core\EventSubscriber\RedirectResponseSubscriber                 sanitizeDestination: 100
  Drupal\Core\EventSubscriber\AjaxResponseSubscriber                     onRequest: 50
  Symfony\Component\HttpKernel\EventListener\RouterListener              onKernelRequest: 32
  Drupal\Core\EventSubscriber\AuthenticationSubscriber                   onKernelRequestFilterProvider: 31
  Drupal\user\EventSubscriber\MaintenanceModeSubscriber                  onKernelRequestMaintenance: 31
  Drupal\Core\EventSubscriber\MaintenanceModeSubscriber                  onKernelRequestMaintenance: 30
  Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber   onRouteMatch: 27
  Drupal\Core\Routing\RoutePreloader                                     onRequest: 0
  Drupal\Core\EventSubscriber\ReplicaDatabaseIgnoreSubscriber            checkReplicaServer: 0
 ---------------------------------------------------------------------- -----------------------------------
use Symfony\Component\HttpKernel\HttpKernel as SymfonyKernelMiddleware;

SymfonyKernelMiddleware::handleRaw(Request $request, $type = self::MASTER_REQUEST) {
  ...
  $event = new GetResponseEvent($this, $request, $type);
  $this->dispatcher->dispatch(KernelEvents::REQUEST, $event);
  ...
  // load controller
  $controller = $this->resolver->getController($request)
  ...
  $event = new FilterControllerEvent($this, $controller, $request, $type);
  $this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event);
  $controller = $event->getController();

  // controller arguments
  $arguments = $this->argumentResolver->getArguments($request, $controller);

  $event = new FilterControllerArgumentsEvent($this, $controller, $arguments, $request, $type);
  $this->dispatcher->dispatch(KernelEvents::CONTROLLER_ARGUMENTS, $event);
  $controller = $event->getController();
  $arguments = $event->getArguments();

  // call controller
  $response = call_user_func_array($controller, $arguments);
  ...
}

Links

Routing

Homework

Founder @

Co- Founder @

Vladyslav Moyseenko, a.k.a vlad.dancer

&

D8 School: Routing, Events

By Vlad Moyseenko

D8 School: Routing, Events

  • 574