Source of file ModuleManager.php
Size: 8,607 Bytes - Last Modified: 2014-03-12T23:21:18+01:00
/home/theseer/Downloads/ZendFramework-2.3.0/library/Zend/ModuleManager/ModuleManager.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 | <?php /** * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ namespace Zend\ModuleManager; use Traversable; use Zend\EventManager\EventManager; use Zend\EventManager\EventManagerInterface; /** * Module manager */ class ModuleManager implements ModuleManagerInterface { /** * @var array An array of Module classes of loaded modules */ protected $loadedModules = array(); /** * @var EventManagerInterface */ protected $events; /** * @var ModuleEvent */ protected $event; /** * @var bool */ protected $loadFinished; /** * modules * * @var array|Traversable */ protected $modules = array(); /** * True if modules have already been loaded * * @var bool */ protected $modulesAreLoaded = false; /** * Constructor * * @param array|Traversable $modules * @param EventManagerInterface $eventManager */ public function __construct($modules, EventManagerInterface $eventManager = null) { $this->setModules($modules); if ($eventManager instanceof EventManagerInterface) { $this->setEventManager($eventManager); } } /** * Handle the loadModules event * * @return void */ public function onLoadModules() { if (true === $this->modulesAreLoaded) { return $this; } foreach ($this->getModules() as $moduleName => $module) { if (is_object($module)) { if (!is_string($moduleName)) { throw new Exception\RuntimeException(sprintf( 'Module (%s) must have a key identifier.', get_class($module) )); } $module = array($moduleName => $module); } $this->loadModule($module); } $this->modulesAreLoaded = true; } /** * Load the provided modules. * * @triggers loadModules * @triggers loadModules.post * @return ModuleManager */ public function loadModules() { if (true === $this->modulesAreLoaded) { return $this; } $this->getEventManager()->trigger(ModuleEvent::EVENT_LOAD_MODULES, $this, $this->getEvent()); /** * Having a dedicated .post event abstracts the complexity of priorities from the user. * Users can attach to the .post event and be sure that important * things like config merging are complete without having to worry if * they set a low enough priority. */ $this->getEventManager()->trigger(ModuleEvent::EVENT_LOAD_MODULES_POST, $this, $this->getEvent()); return $this; } /** * Load a specific module by name. * * @param string|array $module * @throws Exception\RuntimeException * @triggers loadModule.resolve * @triggers loadModule * @return mixed Module's Module class */ public function loadModule($module) { $moduleName = $module; if (is_array($module)) { $moduleName = key($module); $module = current($module); } if (isset($this->loadedModules[$moduleName])) { return $this->loadedModules[$moduleName]; } /* * Keep track of nested module loading using the $loadFinished * property. * * Increment the value for each loadModule() call and then decrement * once the loading process is complete. * * 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; } $event = ($this->loadFinished > 0) ? clone $this->getEvent() : $this->getEvent(); $event->setModuleName($moduleName); $this->loadFinished++; if (!is_object($module)) { $module = $this->loadModuleByName($event); } $event->setModule($module); $this->loadedModules[$moduleName] = $module; $this->getEventManager()->trigger(ModuleEvent::EVENT_LOAD_MODULE, $this, $event); $this->loadFinished--; return $module; } /** * Load a module with the name * @param Zend\EventManager\EventInterface $event * @return mixed module instance * @throws Exception\RuntimeException */ protected function loadModuleByName($event) { $result = $this->getEventManager()->trigger(ModuleEvent::EVENT_LOAD_MODULE_RESOLVE, $this, $event, function ($r) { return (is_object($r)); }); $module = $result->last(); if (!is_object($module)) { throw new Exception\RuntimeException(sprintf( 'Module (%s) could not be initialized.', $event->getModuleName() )); } return $module; } /** * Get an array of the loaded modules. * * @param bool $loadModules If true, load modules if they're not already * @return array An array of Module objects, keyed by module name */ public function getLoadedModules($loadModules = false) { if (true === $loadModules) { $this->loadModules(); } return $this->loadedModules; } /** * Get an instance of a module class by the module name * * @param string $moduleName * @return mixed */ public function getModule($moduleName) { if (!isset($this->loadedModules[$moduleName])) { return null; } return $this->loadedModules[$moduleName]; } /** * Get the array of module names that this manager should load. * * @return array */ public function getModules() { return $this->modules; } /** * Set an array or Traversable of module names that this module manager should load. * * @param mixed $modules array or Traversable of module names * @throws Exception\InvalidArgumentException * @return ModuleManager */ public function setModules($modules) { if (is_array($modules) || $modules instanceof Traversable) { $this->modules = $modules; } else { throw new Exception\InvalidArgumentException(sprintf( 'Parameter to %s\'s %s method must be an array or implement the Traversable interface', __CLASS__, __METHOD__ )); } return $this; } /** * Get the module event * * @return ModuleEvent */ public function getEvent() { if (!$this->event instanceof ModuleEvent) { $this->setEvent(new ModuleEvent); } return $this->event; } /** * Set the module event * * @param ModuleEvent $event * @return ModuleManager */ public function setEvent(ModuleEvent $event) { $this->event = $event; return $this; } /** * Set the event manager instance used by this module manager. * * @param EventManagerInterface $events * @return ModuleManager */ public function setEventManager(EventManagerInterface $events) { $events->setIdentifiers(array( __CLASS__, get_class($this), 'module_manager', )); $this->events = $events; $this->attachDefaultListeners(); return $this; } /** * Retrieve the event manager * * Lazy-loads an EventManager instance if none registered. * * @return EventManagerInterface */ public function getEventManager() { if (!$this->events instanceof EventManagerInterface) { $this->setEventManager(new EventManager()); } return $this->events; } /** * Register the default event listeners * * @return ModuleManager */ protected function attachDefaultListeners() { $events = $this->getEventManager(); $events->attach(ModuleEvent::EVENT_LOAD_MODULES, array($this, 'onLoadModules')); } } |