3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\ModuleManager
;
13 use Zend\EventManager\EventManager
;
14 use Zend\EventManager\EventManagerInterface
;
19 class ModuleManager
implements ModuleManagerInterface
22 * @var array An array of Module classes of loaded modules
24 protected $loadedModules = array();
27 * @var EventManagerInterface
39 protected $loadFinished;
44 * @var array|Traversable
46 protected $modules = array();
49 * True if modules have already been loaded
53 protected $modulesAreLoaded = false;
58 * @param array|Traversable $modules
59 * @param EventManagerInterface $eventManager
61 public function __construct($modules, EventManagerInterface
$eventManager = null)
63 $this->setModules($modules);
64 if ($eventManager instanceof EventManagerInterface
) {
65 $this->setEventManager($eventManager);
70 * Handle the loadModules event
74 public function onLoadModules()
76 if (true === $this->modulesAreLoaded
) {
80 foreach ($this->getModules() as $moduleName => $module) {
81 if (is_object($module)) {
82 if (!is_string($moduleName)) {
83 throw new Exception\
RuntimeException(sprintf(
84 'Module (%s) must have a key identifier.',
88 $module = array($moduleName => $module);
90 $this->loadModule($module);
93 $this->modulesAreLoaded
= true;
97 * Load the provided modules.
99 * @triggers loadModules
100 * @triggers loadModules.post
101 * @return ModuleManager
103 public function loadModules()
105 if (true === $this->modulesAreLoaded
) {
109 $this->getEventManager()->trigger(ModuleEvent
::EVENT_LOAD_MODULES
, $this, $this->getEvent());
112 * Having a dedicated .post event abstracts the complexity of priorities from the user.
113 * Users can attach to the .post event and be sure that important
114 * things like config merging are complete without having to worry if
115 * they set a low enough priority.
117 $this->getEventManager()->trigger(ModuleEvent
::EVENT_LOAD_MODULES_POST
, $this, $this->getEvent());
123 * Load a specific module by name.
125 * @param string|array $module
126 * @throws Exception\RuntimeException
127 * @triggers loadModule.resolve
128 * @triggers loadModule
129 * @return mixed Module's Module class
131 public function loadModule($module)
133 $moduleName = $module;
134 if (is_array($module)) {
135 $moduleName = key($module);
136 $module = current($module);
139 if (isset($this->loadedModules
[$moduleName])) {
140 return $this->loadedModules
[$moduleName];
143 $event = ($this->loadFinished
=== false) ?
clone $this->getEvent() : $this->getEvent();
144 $event->setModuleName($moduleName);
146 $this->loadFinished
= false;
148 if (!is_object($module)) {
149 $module = $this->loadModuleByName($event);
151 $event->setModule($module);
153 $this->loadedModules
[$moduleName] = $module;
154 $this->getEventManager()->trigger(ModuleEvent
::EVENT_LOAD_MODULE
, $this, $event);
156 $this->loadFinished
= true;
162 * Load a module with the name
163 * @param Zend\EventManager\EventInterface $event
164 * @return mixed module instance
165 * @throws Exception\RuntimeException
167 protected function loadModuleByName($event)
169 $result = $this->getEventManager()->trigger(ModuleEvent
::EVENT_LOAD_MODULE_RESOLVE
, $this, $event, function ($r) {
170 return (is_object($r));
173 $module = $result->last();
174 if (!is_object($module)) {
175 throw new Exception\
RuntimeException(sprintf(
176 'Module (%s) could not be initialized.',
177 $event->getModuleName()
185 * Get an array of the loaded modules.
187 * @param bool $loadModules If true, load modules if they're not already
188 * @return array An array of Module objects, keyed by module name
190 public function getLoadedModules($loadModules = false)
192 if (true === $loadModules) {
193 $this->loadModules();
196 return $this->loadedModules
;
200 * Get an instance of a module class by the module name
202 * @param string $moduleName
205 public function getModule($moduleName)
207 if (!isset($this->loadedModules
[$moduleName])) {
210 return $this->loadedModules
[$moduleName];
214 * Get the array of module names that this manager should load.
218 public function getModules()
220 return $this->modules
;
224 * Set an array or Traversable of module names that this module manager should load.
226 * @param mixed $modules array or Traversable of module names
227 * @throws Exception\InvalidArgumentException
228 * @return ModuleManager
230 public function setModules($modules)
232 if (is_array($modules) ||
$modules instanceof Traversable
) {
233 $this->modules
= $modules;
235 throw new Exception\
InvalidArgumentException(sprintf(
236 'Parameter to %s\'s %s method must be an array or implement the Traversable interface',
237 __CLASS__
, __METHOD__
244 * Get the module event
246 * @return ModuleEvent
248 public function getEvent()
250 if (!$this->event
instanceof ModuleEvent
) {
251 $this->setEvent(new ModuleEvent
);
257 * Set the module event
259 * @param ModuleEvent $event
260 * @return ModuleManager
262 public function setEvent(ModuleEvent
$event)
264 $this->event
= $event;
269 * Set the event manager instance used by this module manager.
271 * @param EventManagerInterface $events
272 * @return ModuleManager
274 public function setEventManager(EventManagerInterface
$events)
276 $events->setIdentifiers(array(
281 $this->events
= $events;
282 $this->attachDefaultListeners();
287 * Retrieve the event manager
289 * Lazy-loads an EventManager instance if none registered.
291 * @return EventManagerInterface
293 public function getEventManager()
295 if (!$this->events
instanceof EventManagerInterface
) {
296 $this->setEventManager(new EventManager());
298 return $this->events
;
302 * Register the default event listeners
304 * @return ModuleManager
306 protected function attachDefaultListeners()
308 $events = $this->getEventManager();
309 $events->attach(ModuleEvent
::EVENT_LOAD_MODULES
, array($this, 'onLoadModules'));