3. The HttpFoundation Component defines an object-oriented layer for the HTTP specification. The deepest level is the HttpFoundation component. HttpFoundation provides the main objects needed to deal with HTTP. It is an object-oriented abstraction of some native PHP functions and variables: The Request class abstracts the main PHP global variables like $_GET, $_POST,$_COOKIE, $_FILES, and $_SERVER; The Response class abstracts some PHP functions like header(), setcookie(), and echo; The Session class and SessionStorageInterface interface abstract session management session_*() functions. It provides an abstraction for requests, responses, uploaded files, cookies, sessions, ... The HttpKernel Component provides a structured process for converting a Request into a Response by making use of the event dispatcher Request example use SymfonyComponentHttpFoundationRequest; use SymfonyComponentHttpFoundationResponse; $request = Request::createFromGlobals(); echo $request->getPathInfo();
4. Response example $response = new Response('Not Found', 404, array('Content-Type' => 'text/plain')); $response->send(); The HttpKernel Component provides a structured process for converting a Request into a Response by making use of the event dispatcher On top of HttpFoundation is the HttpKernel component. HttpKernel handles the dynamic part of HTTP It is a thin wrapper on top of the Request and Response classes to standardize the way requests are handled The HttpKernel class is the central class of Symfony and is responsible for handling client requests. Its main goal is to "convert" a Request object to a Response object. HttpKernel notifies events to convert a Request object to a Response one.
5. The EventDispatcher component provides tools that allow your application components to communicate with each other by dispatching events and listening to them Consider the real-world example where you want to provide a plugin system for your project. A plugin should be able to add methods, or do something before or after a method is executed, without interfering with other plugins. This is not an easy problem to solve with single inheritance, and multiple inheritance (were it possible with PHP) has its own drawbacks. Example Once a Response object has been created, it may be useful to allow other elements in the system to modify it (e.g. add some cache headers) before it's actually used. kernel throws an event - kernel.response. Here's how it works: A listener (PHP object) tells a central dispatcher object that it wants to listen to the kernel.response event; At some point, the Symfony kernel tells the dispatcher object to dispatch the kernel.response event, passing with it an Event object that has access to the
6. Concrete implementation kernel.request Dispatched as soon as the request arrives. If any listener return a Response object, all other listeners wont be called. kernel.controller Once the controller is resolved, this event is dispatched and allows changing it. kernel.view Dispatched only if the controller does not return a Response. Its goal is to build a Response object from the return value of the Controller - for example, a string -. kernel.response Allows to modify or replace the Response object after its creation for example, adding the Google Analytics tracker code to every page -. kernel.terminate Dispatched once the Response has been sent. Can be used to run expensive post-response jobs, such as sending mails or processing data. kernel.exception Last chance to convert an Exception into a Response object.
7. The ClassLoader Component loads your project classes automatically if they follow some standard PHP conventions. This gives you a way to upload all your PHP classes so that the files where the classes are defined are only loaded on demand when needed. ClassLoader can load any class as long as you follow the naming conventions This loads project classes right when they are needed, if they are named and set up in directories that follow PHPs PSR-4 interoperability principles. This will help module developers out in a major way; there will be less worrying about module_load_include and similar dancing around to include dependencies, and more calling up classes at runtime to get things done.
8. PSR-4 Standard Example vegetable.module directory structure: modules/vegetable/ css/ js/ src/ Controller/ VegetableController.php class DrupalvegetableController Form/ VegetableForm.php class DrupalvegetableForm Entity/ Tomato.php class DrupalvegetableEntityTomato Cucumber.php class DrupalvegetableEntityCucumber VegetableManager.php class DrupalvegetableVegetableManager templates/ tests/ src/ Entity/ TomatoTest.php class DrupalTestsvegetableEntityTomatoTest CucumberTest.php class DrupalTestsvegetableEntityCucumberTest VegetableManagerTest.php class DrupalTestsvegetableVegetableManagerTest fixtures/ weather-data.json vegetable.info.yml vegetable.routing.yml vegetable.module
9. Explanation: Each module has a namespace that corresponds to its module name. Here: Drupalvegetable The module's namespace is mapped to the ./src/ folder in the module directory. Here: Drupalvegetable modules/vegetable/src/ Anything after the module namespace directly maps to the directory and file structure in the ./src/ folder. Here: DrupalvegetableEntityTomato modules/vegetable/src/Entity/Tomato.php The identical logic applies to PHPUnit tests contained in ./tests/src/.Base namespace Base directory Contains Drupal core DrupalComponent core/lib/Drupal/Co mponent/ Components that are reusable outside of Drupal. DrupalCore core/lib/Drupal/Cor e/ Components that are specific to Drupal. DrupalTests core/tests/Drupal/T ests/ PHPUnit tests of core components. Modules Drupal$modulenam e modules/$modulena me/src/ Main integration files. Drupal$modulenam eTests modules/$modulena me/src/Tests/ Simpletest tests of the module. DrupalTests$modu lename modules/$modulena me/tests/src/ PHPUnit tests of the module.
10. It parses YAML strings and converts them to PHP arrays and vice versa YAML is a human readable data serialization format. YAML can be used in place of XML or JSON. It provides a much more human readable format whilst still being powerful and performant. This format has been especially designed to hold configuration related information, while being as expressive as XML files and as readable as INI files. It allows our modules to initially define their default configuration settings and later allows the site builder to override the same as-and-when instructed to Configuration management means moving between development, staging, and production environments incredibly easy. This gives developers the freedom to work away from production and yet within a similar environment
11. Allows us to load all routes, and dumps a URL matcher or generator specific to these routes. This also means that it maps an HTTP request to a set of configuration variables. As far as Drupal 8 and above versions are concerned, we define our modules routes in a YAML configuration file, each of them set to trigger a specific action that has been defined in our modules classes.
12. Example example.content: path: '/example' defaults: _controller: 'DrupalexampleControllerExampleController::content' custom_arg: 12
13. Drupal 8 introduces the concept of services to decouple reusable functionality and makes these services pluggable and replaceable by registering them with a service container Services are used to perform operations like accessing the database or sending an e-mail. Rather than use PHP's native MySQL functions, we use the core-provided service via the service container to perform this operation so that our code can simply access the database without having to worry about whether the database is MySQL or SQLlite or if the mechanism for sending e-mail is SMTP language_manager: class: DrupalCoreLanguageLanguageManager arguments: ['@language.default'] ... path.alias_manager: class: DrupalCorePathAliasManager arguments: ['@path.crud', '@path.alias_whitelist', '@language_manager'] A service container (or dependency injection container) is a PHP object that A service container (or dependency injection container) is a PHP object that manages the instantiation of services.
14. Comparing Drupal 7 global functions to Drupal 8 services Let's take a look at the code required to invoke a module's hook as an example of the differences between Drupal 7 and 8. In Drupal 7, you would use module_invoke_all('help') to invoke all hook_help() implementations. Because we're calling the module_invoke_all() function directly in our code, there is no easy way for someone to modify the way Drupal invokes modules without making changes to the core function. In Drupal 8, the module_* functions are replaced by the ModuleHandler service. So in Drupal 8 you would use Drupal::moduleHandler()->invokeAll('help'). In this example, Drupal::moduleHandler() locates the registered implementation of the module handler service in via the service container and then calls the invokeAll() method on that service. Advantages 1) it allows a Drupal distribution or hosting provider or another module to override the way invoking modules works by changing the class registered for the module handler service with another 2) The dependencies of code are also better documented 3) the services can be unit tested
15. In Drupal 8 Twig replaces PHPTemplate as the default templating engine One of the results of this change is that all of the theme_* functions and PHPTemplate based *.tpl.php files have been replaced in