ZF2/3 Load Modules from Database

杀马特。学长 韩版系。学妹 提交于 2019-12-07 02:59:27

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

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.

I have done this some time ago by:

  1. Create a "Core" Module responsible with fetching modules from database.
    1.1 In the Module.php add module listener

    public function init(ModuleManagerInterface $manager)
    {
      $sharedEventManger = $manager->getEventManager()->getSharedManager();
      $sharedEventManger->attach(ModuleManager::class, ModuleEvent::EVENT_LOAD_MODULES_POST, new ModuleListener(), 10000); 
    }
    
  2. 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!