Drupal 8 - first impressions (part 2)
Following the sort introduction in Drupal 8 concepts the time has come to get our hands dirty and initiate our first Drupal 8 task: Migrate Cookie Control Module for Drupal 8.
To quickly set a running Drupal 8 environment with apache; mysql, composer and drush 8 Vagrant Drupal Development [1] was used. A simple “vagrant up” and we have an Ubuntu Trusty64 Virtual Box ready to be used with a fresh Drupal 8 installation. We download the latest sources from Drupal’s git repository and using drush site-install we quickly set our new website. The folder structure of Drupal 8 seems rather simplified compared to Drupal 7. All custom and contributed modules are placed in the “modules” folder. We copy the Drupal 7 version of cookie control in the modules folder and also download and enable the drupalmoduleupgrader module, this will assist us in the migration process.
The cookie control Drupal 7 module is fairly simple. There is a configuration page implementing hook_admin_settings, that essentially sets values to the Cookie Control configuration variables and persists them in the database. A page preprocess hook implementation retrieves the configuration variables from the database and handles the corresponding calls to the Cookie Control Javascript API. That’s it more or less. So we are expecting an easy migration to Drupal 8 … Or not ?
As we have already said the drupalmoduleupgrader will assist us in the migration process. Examining the prerequisites of the module we already see a dependency with composer. This is a new one for drupal modules. Before using the module we have to run “composer install” in the module directory to download module’s dependencies like pharborist [2].
We enable drupalmoduleupgrader and then we analyse the Cookie Control module using the corresponding drush command:
drush dmu-analyze cookiecontrol
A rather big report with the parts of the code that needs to be updated is generated.
Below I discuss the list of errors and which part of the Drupal 8 created them:
Configuration
- The Variable API has Been Removed: This is a result of the new configuration management that is introduced in drupal 8. In drupal 8 we have two options to replace the Variable API 1) The State API [3] and 2) The configuration API [4]. The former is an abstraction layer on top of the Key/Value API and handles the serialisation and storage of key/value pairs. The latter one is a namespaced key/value store that doesn’t not use the Key/Value API and the values are Configuration Objects. Configurations Objects have getter and setter methods defined and can be safely serialised to YAML. Modules can provide default configurations in YAML that can be imported in the site. The rule of thumb to select between the State API and the Configuration API is that later one is preferred if we need to transfer the stored data from the staging server to the live server. Taking under consideration that the cookie control is domain specific and variables like the API key cannot be transferred the State API seems more appropriate for the cookie control module.
Entity API
- Node_load() has been Removed: A static method load() is added as replacement in entity classes (i.e. \Drupal\node\Entity\Node, \Drupal\user\Entity\User). Thus the corresponding call is now Node::load(1).
Form API
- Form functions (form_set_error(), form_set_value() moved into FormStateInterface): Following the service oriented architecture all Drupal 7 drupal_*_form() and form_*() functions are now replaced by a form builder service and methods in the $form_state object.
Info file
- .info files are now .info.yml files
- Module info files' core key must have a value of 8.x.
- Info files must contain a type key.
- Module info files' configure key must be a route name, not a path.
Menu/routing
- hook_menu() has been removed from Drupal 8: As we already said drupal 8 uses the routing component of Symfony. Thus there is a total replacement there. All routes should be defined on cookiecontrol.routing.yml and the corresponding controller classes that replace page callbacks should be defined.
- current_path() has been replaced by the route: Another implication of object oriented paradigm used in drupal 8. The static function formRoute of the Url object returns the current page if the ‘’ value is passed as input to the function.
Rendering
- drupal_add_js() has been removed: Drupal 8 uses a new way of loading assets (css, js) [5] only when they are needed. The first step to load assets is to define a library that contains css and/or js files and then attach this library in a render array using a hook.
System
- drupal_http_request() has been replaced by Guzzle: As we already said drupal 8 incorporates the Guzzle component that is an http client. The \Drupal::httpClient() method gives access to Guzzle via the http client service. For more information read [6].
- ip_address() has been removed: The replacement of ip_address() is the Request::getClientIp(). To access the current request object Drupal::request can be used, otherwise an object should be registered in the service container and depend on the request service [7].
- l() has been removed: Two new static factory methods Url::fromRoute, and Url::fromUri are introduced in \Drupal\Core\Url as a replacement of l() function
Theme System
- theme() has been renamed to _theme(), and should never be called directly: Direct invocation of theme() function is not allowed in Drupal 8. Render arrays should be built as a replacement.
Summarising for a relitively simple module we have a rather big list of errors to fix and we have not mentioned the folder/sources restructuring based on the PSR-4 specification. So there is work to be done to complete the migration. In the next post we will try the automated migration provided by drupalmoduleupgrader module and document the process towards implementing the drupal 8 cookiecontrol module.
To be continued…
Take a look at our web design and development services to see where we can help.
--
References
[1]: https://www.drupal.org/project/vdd
[2]: https://github.com/grom358/pharborist
[3]: https://www.drupal.org/developing/api/8/state
[4]: https://www.drupal.org/developing/api/8/configuration
[5]: https://www.drupal.org/developing/api/8/assets
[6]: https://www.drupal.org/node/1862446
[7]: https://www.drupal.org/node/1969794