From b423f3b5fb5ca40f8a03d15738b796966c1d6588 Mon Sep 17 00:00:00 2001 From: Aleksey Khudyakov Date: Sun, 6 Sep 2015 15:32:06 +1000 Subject: [PATCH 1/4] Add module manager option not to use Zend\Loader New `use_zend_loader` module manager option controls if Zend\Loader should be used, it is enabled by default. Disabling it removes dependency on zendframework/zend-loader. This option is useful if alternative autoloading is used, eg Composer. Setting it to false will also disable AutoloaderProvider feature. --- src/Listener/DefaultListenerAggregate.php | 20 ++++++--- src/Listener/ListenerOptions.php | 32 +++++++++++++ .../Listener/DefaultListenerAggregateTest.php | 45 ++++++++++++++++++- 3 files changed, 89 insertions(+), 8 deletions(-) diff --git a/src/Listener/DefaultListenerAggregate.php b/src/Listener/DefaultListenerAggregate.php index e1a56a6..91ec2b8 100644 --- a/src/Listener/DefaultListenerAggregate.php +++ b/src/Listener/DefaultListenerAggregate.php @@ -41,17 +41,23 @@ public function attach(EventManagerInterface $events, $priority = 1) $options = $this->getOptions(); $configListener = $this->getConfigListener(); $locatorRegistrationListener = new LocatorRegistrationListener($options); - $moduleLoaderListener = new ModuleLoaderListener($options); // High priority, we assume module autoloading (for FooNamespace\Module - // classes) should be available before anything else - $moduleLoaderListener->attach($events); - $this->listeners[] = $moduleLoaderListener; + // classes) should be available before anything else. + // Register it only if use_zend_loader config is true, however. + if ($options->useZendLoader()) { + $moduleLoaderListener = new ModuleLoaderListener($options); + $moduleLoaderListener->attach($events); + $this->listeners[] = $moduleLoaderListener; + } $this->listeners[] = $events->attach(ModuleEvent::EVENT_LOAD_MODULE_RESOLVE, new ModuleResolverListener); - // High priority, because most other loadModule listeners will assume - // the module's classes are available via autoloading - $this->listeners[] = $events->attach(ModuleEvent::EVENT_LOAD_MODULE, new AutoloaderListener($options), 9000); + if ($options->useZendLoader()) { + // High priority, because most other loadModule listeners will assume + // the module's classes are available via autoloading + // Register it only if use_zend_loader config is true, however. + $this->listeners[] = $events->attach(ModuleEvent::EVENT_LOAD_MODULE, new AutoloaderListener($options), 9000); + } if ($options->getCheckDependencies()) { $this->listeners[] = $events->attach( diff --git a/src/Listener/ListenerOptions.php b/src/Listener/ListenerOptions.php index f23c149..fd754b6 100644 --- a/src/Listener/ListenerOptions.php +++ b/src/Listener/ListenerOptions.php @@ -67,6 +67,11 @@ class ListenerOptions extends AbstractOptions */ protected $moduleMapCacheKey; + /** + * @var bool + */ + protected $useZendLoader = true; + /** * Get an array of paths where modules reside * @@ -381,6 +386,33 @@ public function setCheckDependencies($checkDependencies) return $this; } + /** + * Whether or not to use zend-loader to autoload modules. + * + * @return bool + */ + public function useZendLoader() + { + return $this->useZendLoader; + } + + /** + * Set a flag indicating if the module manager should use zend-loader + * + * Setting this option to false will disable ModuleAutoloader, requiring + * other means of autoloading to be used (e.g., Composer). + * + * If disabled, the AutoloaderProvider feature will be disabled as well + * + * @param bool $flag + * @return ListenerOptions + */ + public function setUseZendLoader($flag) + { + $this->useZendLoader = (bool) $flag; + return $this; + } + /** * Normalize a path for insertion in the stack * diff --git a/test/Listener/DefaultListenerAggregateTest.php b/test/Listener/DefaultListenerAggregateTest.php index f7b504c..405da99 100644 --- a/test/Listener/DefaultListenerAggregateTest.php +++ b/test/Listener/DefaultListenerAggregateTest.php @@ -66,7 +66,7 @@ public function testDefaultListenerAggregateCanAttachItself() ]; foreach ($expectedEvents as $event => $expectedListeners) { $this->assertContains($event, $events); - $count = 0; + $count = 0; foreach ($this->getListenersForEvent($event, $moduleManager->getEventManager()) as $listener) { if (is_array($listener)) { $listener = $listener[0]; @@ -94,4 +94,47 @@ public function testDefaultListenerAggregateCanDetachItself() $listenerAggregate->detach($events); $this->assertEquals(1, count($this->getEventsFromEventManager($events))); } + + public function testDefaultListenerAggregateSkipsAutoloadingListenersIfZendLoaderIsNotUsed() + { + $moduleManager = new ModuleManager(['ListenerTestModule']); + $eventManager = $moduleManager->getEventManager(); + $listenerAggregate = new DefaultListenerAggregate(new ListenerOptions([ + 'use_zend_loader' => false, + ])); + $listenerAggregate->attach($eventManager); + + $events = $this->getEventsFromEventManager($eventManager); + $expectedEvents = [ + 'loadModules' => [ + 'config-pre' => 'Zend\ModuleManager\Listener\ConfigListener', + 'config-post' => 'Zend\ModuleManager\Listener\ConfigListener', + 'Zend\ModuleManager\Listener\LocatorRegistrationListener', + 'Zend\ModuleManager\ModuleManager', + ], + 'loadModule.resolve' => [ + 'Zend\ModuleManager\Listener\ModuleResolverListener', + ], + 'loadModule' => [ + 'Zend\ModuleManager\Listener\ModuleDependencyCheckerListener', + 'Zend\ModuleManager\Listener\InitTrigger', + 'Zend\ModuleManager\Listener\OnBootstrapListener', + 'Zend\ModuleManager\Listener\ConfigListener', + 'Zend\ModuleManager\Listener\LocatorRegistrationListener', + ], + ]; + foreach ($expectedEvents as $event => $expectedListeners) { + $this->assertContains($event, $events); + $count = 0; + foreach ($this->getListenersForEvent($event, $eventManager) as $listener) { + if (is_array($listener)) { + $listener = $listener[0]; + } + $listenerClass = get_class($listener); + $this->assertContains($listenerClass, $expectedListeners); + $count += 1; + } + $this->assertSame(count($expectedListeners), $count); + } + } } From 74f06db1b0321485cd673cc5a4cde404c1b62928 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 11 Jul 2017 10:35:55 -0500 Subject: [PATCH 2/4] Adds more descriptive info to zend-loader composer suggestion --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e34d3cc..e11728e 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ }, "suggest": { "zendframework/zend-console": "Zend\\Console component", - "zendframework/zend-loader": "Zend\\Loader component", + "zendframework/zend-loader": "Zend\\Loader component if you are not using Composer autoloading for your modules", "zendframework/zend-mvc": "Zend\\Mvc component", "zendframework/zend-servicemanager": "Zend\\ServiceManager component" }, From 0000db592ee543cf581b7650935b778d2fccc2c9 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 11 Jul 2017 10:41:48 -0500 Subject: [PATCH 3/4] Documents the use_zend_loader option - Within the `ModuleAutoloader` chapter, a new note documents the new option. --- doc/book/module-autoloader.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/doc/book/module-autoloader.md b/doc/book/module-autoloader.md index cf9148f..f3996c8 100644 --- a/doc/book/module-autoloader.md +++ b/doc/book/module-autoloader.md @@ -60,6 +60,33 @@ $moduleManager->loadModules(); > than one registered module path, the module autoloader will return the first > one it finds. +> ### Disabling the ModuleAutoloader +> +> - Since 2.8.0 +> +> If you are using Composer to autoload, you may not need to use the +> `ModuleAutolaoder`. As such, you can disable it by passing the following +> option to the `ListenerOptions` class: +> +> ```php +> 'use_zend_loader' => false, +> ``` +> +> If your project was begun from the [skeleton application](https://github.com/zendframework/ZendSkeletonApplication), +> place the above within the `module_listener_options` configuration of your +> `config/application.config.php` file: +> +> ```php +> return [ +> /* ... */ +> 'module_listener_options' => [ +> 'use_zend_loader' => false, +> /* ... */ +> ], +> /* ... */ +> ]; +> ``` + ## Non-Standard / Explicit Module Paths Sometimes you may want to specify exactly where a module is instead of having From 01619514cceeae1638a1211ab4bff3be9b210bf7 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 11 Jul 2017 10:43:21 -0500 Subject: [PATCH 4/4] Added CHANGELOG for #4 --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4875597..8d9a7c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,11 @@ All notable changes to this project will be documented in this file, in reverse ### Added -- Nothing. +- [#44](https://github.com/zendframework/zend-modulemanager/pull/44) adds a new + `ListenerOptions` option, `use_zend_loader`. The option defaults to `true`, + which keeps the current behavior of registering the `ModuleAutoloader` and + `AutoloaderProvider`. If you disable it, these features will no longer be + loaded, allowing `ModuleManager` to be used without zend-loader. ### Deprecated