Latest sites

Quick news

  • 2014-03-27: MongoDB Watchdog module ported to Drupal 8 at the Szeged Dev Days.
  • 2014-01-26: My post on the Symfony web profiler in Silex selected in Week of Symfony. w00t !
  • 2013-10-18: My first commit went into MongoDB today. And, guess what ? It's in JavaScript
  • 2013-09-20 to 29: Working on Drupal 8 EntityAPI at the extended code sprints during and around DrupalCon Prague
  • 2012-08-19: Working on Drupal 8 EntityAPI at Drupalcon Munich
  • 2012-06-15: Working on Drupal 8 EntityAPI at DrupalDevDays Barcelona
  • 2012-03-23: Working on the future Drupal Document Oriented Storage at DrupalCon Denver. D8 or later ? Bets are on Later

Drupal 8 tip of the day: autoloaded code in a module install file

Autoloading in D8 is much more convenient that in previous versions, however, it still has limitations. One such issue is with hook_requirements(), which is supposed to be present in the module install file, not the module itself: when called at runtime for the site report page, the module is loaded and the PSR/4 autoloader works fine. However, when that hook is fired during install to ensure the module can indeed be enabled, the module is not yet enabled, and the autoloader is not yet able to find code from that module, meaning the hook_requirements('install') implementation cannot use namespaced classes from the module, as they will not be autoloadable. What are the solutions ?

The bad
The first solution is obvious but painful : since the file layout within the module is known at the time of committing, it is possible to avoid autoloading using require_once for each class/interface/trait needed by the code, typically like this:

// to male \Drupal\mymodule\Some\Namespace\Class available in mymodule_requirements().
require_once __DIR__ . '/src/Some/Namespace/Class.php';
// ... for each such class

The good
But there is a better way: just make the classloader aware of the module being installed:

// Not needed at runtime.
if ($phase === 'install') {
$module = 'mymodule';
drupal_classloader_register($module, drupal_get_path('module', $module));

During module enabling, its path is already known, so drupal_get_path can be used. With this little help, the module autoloaded code will be available during the install, and allow the hook_requirements() implementation to use it.

The ugly

One obvious temptation would be to put the hook_requirements() implementation in the module file, reasoning that, since if is in the module file, it implies that the module is available when the hook is fired. And indeed, this works for hook_requirements('runtime').

However, during install, the module is still not loaded, so the implementation for hook_requirements('install') is simply not found and the requirements check is ignored. Don't do it.