0

I am trying to load modules on the basis of user type in addition to Application module i.e. Application modules is always loaded since it is mentioned in application.config.php file if user is of type 1 I want to load module A, B and D and if user is of type 2, I want to load module C, E and F.

in Module.php of Application module's onBootstrap function I load modules dynamically, and when I see the result var_dump($moduleManager->loadedModules()), it shows the array of the correct modules that are loaded

But the issue that I am facing is that even though modules are loaded correctly their configuration is not loaded.

Example:

In my module A I have a service called, SomethingService and it is being used in indexAction of IndexController in Application module. But it throws the exception which states

Unable to fetch or create instance of SomethingService

After some debugging I found that even though the modules are loaded their configuration from module.config.php is not loaded and is not availble in Config service.

To overcome this issue, where I load module, I now get the config using $module->getConfig() method merge if with the Config service and override Config service using the following code

$this->serviceLocator->setAllowOverride(true);
$this->serviceLocator->setService('config', $mergedConfig);
$this->serviceLocator->setAllowOverride(false);

As a result of this , when I get config using $this->serviceLocator->get('config); I see that all the modules config is merged and is available in the config array.

After doing all of this, I am still getting the exception that I mentioned above. Maybe I am doing all of this at the wrong location?

halfer
  • 19,824
  • 17
  • 99
  • 186
Haris Mehmood
  • 854
  • 4
  • 15
  • 26
  • Could you show me, how do you call `SomethingService` in `IndexController`? – Dolly Aswin Jul 24 '17 at 09:34
  • @DollyAswin `$service = $this->serviceLocator->get('SomethingService');` Yes, serviceLocator is injected into the controller, yes service is declared in factories by the name of `SomethingService` – Haris Mehmood Jul 24 '17 at 09:57
  • OK, could you show me the `service_manager` or `factories` configuration. This error caused by the service not created – Dolly Aswin Jul 24 '17 at 10:22
  • @DollyAswin I did var_dump for the service I am getting error for and this is what I am getting `/app/module/Application/Module.php:458:string 'ModuleA\Factory\Mapper\SomethingServiceFactory' (length=37)` – Haris Mehmood Jul 24 '17 at 10:24
  • That is not help, please edit the question with your `Factories` configuration, just on `ModuleA\Factory\Mapper\SomethingServiceFactory` section. And please also put the error messages. This error caused by the `factory` not created successfully. – Dolly Aswin Jul 24 '17 at 10:29
  • @DollyAswin the issue is not with the factory or configuration values, if I load all modules by application.config.php it works without error, the issue is with dynamically loading the modules, rather than the factory or config values. :) Thank you for your help – Haris Mehmood Jul 24 '17 at 10:30

1 Answers1

0

Based on your comment, if you load all modules by application.config.php it works without error, and the issue is with dynamically loading the modules.

And I analiyze this caused by Application module has been bootstraped, so your controller didn't find the SomethingService. Because you load modules in onBootstrap(Event $e) method.

onBootstrap(Event $e) method is called immediately after all modules have been bootstraped.

So, IndexController have been configured first. That's why it cannot find the SomethingService

I think you need to load modules in init(ModuleManager $moduleManager) method instead of onBootstrap(Event $e).

init(ModuleManager $moduleManager) is called before the module is bootstrapped.

class Module
{
    public function init(ModuleManager $moduleManager)
    {
        // Remember to keep the init() method as lightweight as possible
    }
}
Dolly Aswin
  • 2,684
  • 1
  • 20
  • 23
  • I can not access ServiceManager in init method, is there a way, I can load modules on `loadModules.post` event without breaking the app ? – Haris Mehmood Jul 24 '17 at 12:43
  • Although I have been through this routine, I know we can load modules in init method, but this is before the serviceManager is loaded and we can not access the services like doctrine , zendDb or zfcuser_auth_service, I need zfcuser_auth service to load modules based on user role , i hope you understand what I am trying to achieve here – Haris Mehmood Jul 24 '17 at 12:45
  • @HarisMehmood You can get the ServiceManager in the init method. Try `$sm = $e->getParam('ServiceManager');` in your modules `init()` method. – Crisp Jul 24 '17 at 20:08
  • @Crisp hi, thanks for this, but even if I get `serviceManager` in `init(ModuleManager $moduleManager)` the services are not yet loaded :) – Haris Mehmood Jul 25 '17 at 03:54