diff --git a/src/ModuleManager.php b/src/ModuleManager.php index 01376d0..46db74b 100644 --- a/src/ModuleManager.php +++ b/src/ModuleManager.php @@ -40,9 +40,9 @@ class ModuleManager implements ModuleManagerInterface protected $event; /** - * @var bool + * @var int */ - protected $loadFinished; + protected $loadFinished = 0; /** * modules @@ -51,6 +51,18 @@ class ModuleManager implements ModuleManagerInterface */ protected $modules = []; + /** + * Childs dependency modules + * + * @var array + */ + protected $childsModules = []; + + /** + * @var string + */ + protected $parentModule; + /** * True if modules have already been loaded * @@ -100,6 +112,24 @@ public function onLoadModules() $this->modulesAreLoaded = true; } + /** + * Load childs dependency modules + * + * @param ModuleEvent $e + * @return void + */ + public function onLoadChildsModules(ModuleEvent $e) + { + if (!$this->parentModule || !isset($this->childsModules[$this->parentModule])) { + return; + } + + foreach ($this->childsModules[$this->parentModule] as $module) { + $this->loadModule($module); + } + unset($this->childsModules[$this->parentModule]); + } + /** * Load the provided modules. * @@ -140,7 +170,7 @@ public function loadModules() * @triggers loadModule * @return mixed Module's Module class */ - public function loadModule($module) + public function loadModule($module, $afterCurrent = false) { $moduleName = $module; if (is_array($module)) { @@ -162,8 +192,12 @@ public function loadModule($module) * To load a module, we clone the event if we are inside a nested * loadModule() call, and use the original event otherwise. */ - if (!isset($this->loadFinished)) { - $this->loadFinished = 0; + if ($this->loadFinished > 0 && $this->parentModule && $afterCurrent) { + $childModule = is_object($module) + ? [$moduleName=>$module] + : $moduleName; + $this->childsModules[$this->parentModule][] = $childModule; + return; } $event = ($this->loadFinished > 0) ? clone $this->getEvent() : $this->getEvent(); @@ -178,6 +212,7 @@ public function loadModule($module) $event->setName(ModuleEvent::EVENT_LOAD_MODULE); $this->loadedModules[$moduleName] = $module; + $this->parentModule = $event->getModuleName(); $this->getEventManager()->triggerEvent($event); $this->loadFinished--; @@ -339,5 +374,6 @@ public function getEventManager() protected function attachDefaultListeners($events) { $events->attach(ModuleEvent::EVENT_LOAD_MODULES, [$this, 'onLoadModules']); + $events->attach(ModuleEvent::EVENT_LOAD_MODULE, [$this, 'onLoadChildsModules'], -100); } } diff --git a/test/Listener/ConfigListenerTest.php b/test/Listener/ConfigListenerTest.php index 692416e..4d6ae06 100644 --- a/test/Listener/ConfigListenerTest.php +++ b/test/Listener/ConfigListenerTest.php @@ -346,12 +346,12 @@ public function testConfigListenerFunctionsAsAggregateListener() $moduleManager = $this->moduleManager; $events = $moduleManager->getEventManager(); - $this->assertEquals(2, count($this->getEventsFromEventManager($events))); + $this->assertEquals(3, count($this->getEventsFromEventManager($events))); $configListener->attach($events); $this->assertEquals(4, count($this->getEventsFromEventManager($events))); $configListener->detach($events); - $this->assertEquals(2, count($this->getEventsFromEventManager($events))); + $this->assertEquals(3, count($this->getEventsFromEventManager($events))); } } diff --git a/test/Listener/DefaultListenerAggregateTest.php b/test/Listener/DefaultListenerAggregateTest.php index f7b504c..ee7e063 100644 --- a/test/Listener/DefaultListenerAggregateTest.php +++ b/test/Listener/DefaultListenerAggregateTest.php @@ -62,6 +62,7 @@ public function testDefaultListenerAggregateCanAttachItself() 'Zend\ModuleManager\Listener\OnBootstrapListener', 'Zend\ModuleManager\Listener\ConfigListener', 'Zend\ModuleManager\Listener\LocatorRegistrationListener', + 'Zend\ModuleManager\ModuleManager', ], ]; foreach ($expectedEvents as $event => $expectedListeners) { @@ -86,12 +87,12 @@ public function testDefaultListenerAggregateCanDetachItself() $moduleManager = new ModuleManager(['ListenerTestModule']); $events = $moduleManager->getEventManager(); - $this->assertEquals(1, count($this->getEventsFromEventManager($events))); + $this->assertEquals(2, count($this->getEventsFromEventManager($events))); $listenerAggregate->attach($events); $this->assertEquals(4, count($this->getEventsFromEventManager($events))); $listenerAggregate->detach($events); - $this->assertEquals(1, count($this->getEventsFromEventManager($events))); + $this->assertEquals(2, count($this->getEventsFromEventManager($events))); } } diff --git a/test/ModuleManagerTest.php b/test/ModuleManagerTest.php index 8561524..3a16b4a 100644 --- a/test/ModuleManagerTest.php +++ b/test/ModuleManagerTest.php @@ -233,4 +233,21 @@ public function testGetEventWillLazyLoadOneWithTargetSetToModuleManager() $this->assertInstanceOf(ModuleEvent::class, $event); $this->assertSame($moduleManager, $event->getTarget()); } + + public function testLoadChildsModules() + { + $moduleManager = new ModuleManager(['LoadChildsModule'], $this->events); + $this->defaultListeners->attach($this->events); + $moduleManager->loadModules(); + + $this->assertSame( + ['LoadChildsModule', 'LoadChildsModule2', 'BarModule', 'SomeModule'], + array_keys($moduleManager->getLoadedModules()) + ); + + $this->assertArraySubset( + ['bar' => 'foo', 'some' => 'thing'], + $this->defaultListeners->getConfigListener()->getMergedConfig(false) + ); + } } diff --git a/test/TestAsset/LoadChildsModule/Module.php b/test/TestAsset/LoadChildsModule/Module.php new file mode 100644 index 0000000..0a10ff8 --- /dev/null +++ b/test/TestAsset/LoadChildsModule/Module.php @@ -0,0 +1,27 @@ +loadModule('LoadChildsModule2', 'after'); + $moduleManager->loadModule(['SomeModule' => new \SomeModule\Module()], 'after'); + } + + public function getConfig() + { + return [ + 'bar' => 'SubModule', + ]; + } +} diff --git a/test/TestAsset/LoadChildsModule2/Module.php b/test/TestAsset/LoadChildsModule2/Module.php new file mode 100644 index 0000000..3ec5c38 --- /dev/null +++ b/test/TestAsset/LoadChildsModule2/Module.php @@ -0,0 +1,26 @@ +loadModule('BarModule', 'after'); + } + + public function getConfig() + { + return [ + 'bar' => 'SubModule', + ]; + } +} diff --git a/test/TestAsset/LoadChildsModule2/configs/config-c832f68.php b/test/TestAsset/LoadChildsModule2/configs/config-c832f68.php new file mode 100644 index 0000000..e6c7224 --- /dev/null +++ b/test/TestAsset/LoadChildsModule2/configs/config-c832f68.php @@ -0,0 +1,4 @@ + 'thing', +];