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
- Literal segments.
/admin/content
- Route parameters with constraints.
/node/add/{node_type}, /node/add/{node}
- Route parameters without constraints.
/file/progress/{key}
- Wildcard parameters segments with constraints.
No support - 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