问题
I would like to know if there is a way to load modules from a database table in zend framework 2 preferable 3? I want to be able to dynamically disable or enable modules based on a status column inside a database table
回答1:
I'm pretty sure you can accomplish this by attaching listener to some of ModuleManager
events.
There are docs for v3 https://docs.zendframework.com/zend-modulemanager/module-manager/ and v2 https://framework.zend.com/manual/2.1/en/modules/zend.module-manager.module-manager.html
And don't forget autoloading for v3
回答2:
By reading your question tom_cruz, I realize that I have exactly the same one ;-)
I went through the ZF2 source code of ModuleManager, ModuleManagerFactory, ModuleEvent and some listeners. After analyzing the flow, my new question is:
"What do I expect from an active/inactive module?"
Nearly every important stuff is done by the events Nemutaisama mentioned. i.e. loading config by adding getConfig() Method to the Module.php class.
ATM I'm not able to answer the above question. I'll come back to this one laters. But right now, I think it's an application problem, not a framework one.
回答3:
I have done this some time ago by:
Create a "Core" Module responsible with fetching modules from database.
1.1 In the Module.php add module listenerpublic function init(ModuleManagerInterface $manager) { $sharedEventManger = $manager->getEventManager()->getSharedManager(); $sharedEventManger->attach(ModuleManager::class, ModuleEvent::EVENT_LOAD_MODULES_POST, new ModuleListener(), 10000); }
Module Listener created by me was something like:
public function __invoke(ModuleEvent $event) { $target = $event->getTarget(); $serverName = $_SERVER['SERVER_NAME']; if(! $serverName) { return; } //module ok if(! $target instanceof ModuleManagerInterface) { return; } //config data $configListener = $event->getConfigListener(); $config = $configListener->getMergedConfig(false); //app modules $modules = $target->getModules(); //select active modules $adapter = new Adapter($config['db']); $sql = new Sql($adapter); $select = $sql->select(['c' => 'customers']) ->join(['cm' => 'customers_modules'], 'cm.customer_id = c.id', ['module' => 'module']) ->where(['c.domain' => $serverName]) ->where(['cm.active' => 1]); $statement = $sql->prepareStatementForSqlObject($select); $result = $statement->execute(); if($result instanceof ResultInterface && $result->isQueryResult() && $result->getAffectedRows()) { //change db connection params here (if you use different db for customers) while ($current = $result->current()) { if (! in_array($current['module'], $modules)) { try { $target->loadModule($current['module']) ; } catch (\RuntimeException $e) { $target->loadModule('WQ' . str_replace($current['prefix'], '', $current['module'])); } $modules[] = $current['module']; $module = $target->getModule($current['module']); if (($module instanceof ConfigProviderInterface) || (is_callable([$module, 'getConfig']))) { $moduleConfig = $module->getConfig(); $config = ArrayUtils::merge($config, $moduleConfig); } } $result->next(); } } $target->setModules($modules); $configListener->setMergedConfig($config); }
Hope it was useful.
来源:https://stackoverflow.com/questions/44549601/zf2-3-load-modules-from-database