7

I have a good amount of experience with D7 but not much with D8, so I'm wondering about the "proper" D8 way of doing things here.

So I've got ModuleA and ModuleB

ModuleB depends on ModuleA.

I need to call a function from ModuleA inside of ModuleB.

In D7, this was done by module_load_include(), and D8 appears to have both this function as well as the ModuleHandler class.

I am trying to instantiate this class and use the load method, but it is throwing an error because I am passing nothing to the constructor:

$module_handler = new \Drupal\Core\Extension\ModuleHandler; $module_handler->load('ilib_connect');

TypeError: Argument 3 passed to Drupal\Core\Extension\ModuleHandler::__construct() must implement interface Drupal\Core\Cache\CacheBackendInterface, none given, called in /var/www/company/web/modules/custom/ilib_sso/ilib_sso.module on line 31 in Drupal\Core\Extension\ModuleHandler->__construct() (line 109 of core/lib/Drupal/Core/Extension/ModuleHandler.php).

So I'm not passing anything currently to the constructor (not sure what precisely to pass), and calling the method statically is not a problem, because the load() method references its object and thus causes this error:

Error: Using $this when not in object context in Drupal\Core\Extension\ModuleHandler::load() (line 122 of core/lib/Drupal/Core/Extension/ModuleHandler.php).

So how am I supposed to use this particular class? Or should I just use module_load_include()?

What is the Drupal 8 way of doing things?

6
  • So, you need to call procedural code from Module A from w/in Module B procedural code, and Module A's code is in an include?
    – mpdonadio
    Commented Dec 28, 2016 at 21:50
  • The module handler is a service; use \Drupal::moduleHandler(), or inject into your own container aware class, to get a fully instantiated version
    – Clive
    Commented Dec 28, 2016 at 21:51
  • use \Drupal::ModuleHandler(); seems to be throwing an syntax error.
    – Jack Ryan
    Commented Dec 28, 2016 at 21:58
  • 1
    Just \Drupal::moduleHandler()->loadInclude($foo, $bar);, (the "use" is part of text in that last comment, not the code, can understand why it's confusing)
    – Clive
    Commented Dec 28, 2016 at 22:03
  • 1
    Note: While it still exists, there should be very few reasons to still having to use it in 8.x. It is only necessary if a module has (api) functions in a separate file that is not automatically loaded. This should not be done anymore, that's what services are for in 8.x. Sounds like a module that has not been fully ported to 8.x concepts or written with 7.x concepts.
    – Berdir
    Commented Dec 29, 2016 at 7:30

1 Answer 1

7

The answer is that the load method isn't the correct method, and there's a specific loadInclude() method.

\Drupal::moduleHandler()->loadInclude('ilib_connect', 'module');
3
  • 2
    ModuleHandler::loadInclude isn't static, you shouldn't invoke it statically, the fact that you can is just a remnant of old PHP nonsense, it will generate E_STRICT in PHP5, possibly worse in 7. Also from the Drupal side, it might cause you no problems now, but if the implementation changes (e.g. to use $this) it could scupper you in the future. Getting the service instance into your current context is the way to go
    – Clive
    Commented Dec 28, 2016 at 21:54
  • 1
    Alright, I'll delete this then.
    – Jack Ryan
    Commented Dec 28, 2016 at 21:56
  • 2
    Or you could just edit it, the correct out-of-container methodology is: \Drupal::moduleHandler()->loadInclude($foo, $bar);
    – Clive
    Commented Dec 28, 2016 at 21:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.