How to run Laminas ModuleManager in a standalone project

Hi everybody, i created a project with laminas components. In this project like expressive there is no ModuleManager to load to some modules.

But
i want to init Laminas\I18n\ConfigProvider using Laminas\I18n\Module.php.
Could you someone show me a standalone example how can i init Laminas\I18n\Module.php using Laminas\ModuleManager\ModuleManager component.

i tried this but i don’t know what i need to do how to load and pass it to service manager.

$container = new Laminas\ServiceManager\ServiceManager;
$container->setAlias('config', Laminas\Config\Config::class);
(new Config($container->get(Laminas\Config\Config::class)->dependencies->toArray()))
    ->configureServiceManager($container);

$moduleManager = new Laminas\ModuleManager\ModuleManager(['Zend\I18n\Module']);
$moduleManager->loadModules();

Thanks.

A few comments first on your code.

  • You mention you want to add laminas-i18n… but your code snippet uses zend-i18n. That’s a problem right there.
  • When you pass a module to the ModuleManager, you should use the namespace of the Module class you want to use, but not the class name. So, here, use Laminas\I18n.
  • You’re going to run into issues in lines 2 and 3 of your example. You’ve aliased ‘config’ to Laminas\Config\Config::class, without having first defined the Laminas\Config\Config service; you cannot alias to a non-existent service. You then pull the Laminas\Config\Config::class as a service in order to operate on it, but it’s not been defined yet. Fetch your configuration and/or build it, add it as a service to your container (using the name “config”, as that’s what most components expect), and then pull the dependencies and use those to configure the container. It MUST be in that order.

Now, to answer the stated question, which is how to use the ModuleManager standalone, I suggest you take a look at how the laminas-mvc ModuleManagerFactory does it.

The missing piece is that you do not have the default set of listeners attached to the event manager instance used by the ModuleManager, so there’s no actual processing done. At the very least, you need to create an EventManager instance and attach the Laminas\ModuleManager\Listener\DefaultListenerAggregate to it, and pass that to the ModuleManager constructor when you instantiate it:

use Laminas\EventManager\EventManager;
use Laminas\ModuleManager;

$eventManager = new EventManager();
$listeners = new ModuleManager\Listener\DefaultListenerAggregate($config['module_listener_options'] ?? []);
$listeners->attach($eventManager);

$moduleManager = new ModuleManager\ModuleManager([
    'Laminas\I18n',
], $eventManager);
$moduleManager->loadModules();

Hello first of all thanks for your detailed answer.

I did as you said below, the module seems loaded but after the module was loaded I was expecting module dependencies to combine with global dependencies.
Dependencies seem to be empty. Is this normal behavior, what should I do to combine dependencies ?

I have made this sample into a repository so that you can easily access it: https://github.com/obullo/Module

Thanks for your help, I appreciate it :slight_smile:

<?php
require 'vendor/autoload.php';

use Laminas\EventManager\EventManager;
use Laminas\ModuleManager;
use Laminas\ModuleManager\Listener\{
	ListenerOptions,
	DefaultListenerAggregate
};
use Laminas\ServiceManager\ServiceManager;
use Laminas\ModuleManager\ModuleEvent;
use Laminas\ModuleManager\Listener\ServiceListener;

$container = new ServiceManager;
$container->setFactory(Laminas\Config\Config::class, 'App\Factory\ConfigFactory');
$container->setAlias('config', Laminas\Config\Config::class);
$container->setService('ServiceListener', new ServiceListener($container));
$config = $container->get('config');
$serviceListener = $container->get('ServiceListener');

// https://github.com/laminas/laminas-mvc/blob/master/src/Service/ModuleManagerFactory.php
//
$serviceListener->addServiceManager(
    $container,
    'service_manager',
    'Laminas\ModuleManager\Feature\ServiceProviderInterface',
    'getServiceConfig'
);
$events = new EventManager;
$listenerOptions  = new ListenerOptions($config['module_listener_options']);
$defaultListeners = new DefaultListenerAggregate($listenerOptions);
$serviceListener  = $container->get('ServiceListener');

$defaultListeners->attach($events);
$serviceListener->attach($events);

$moduleEvent = new ModuleEvent;
$moduleEvent->setParam('ServiceManager', $container);

$moduleManager = new ModuleManager\ModuleManager([
    'Laminas\I18n',
], $events);
$moduleManager->setEvent($moduleEvent);
$moduleManager->loadModules();
$module = $moduleManager->getModule('Laminas\I18n');

var_dump($module);  

// Output: 
// object(Laminas\I18n\Module)#34 (0) { } 
// 
var_dump($config->toArray());  

// Output: 
// array(1) { ["dependencies"]=> array(5) { ["initializers"]=> array(0) { } ["aliases"]=> array(0) { } ["invokables"]=> array(0) { } ["factories"]=> array(0) { } ["abstract_factories"]=> array(0) { } } }

Can you explain what your goal is? Do you want to use the module-manager or do you want use laminas-i18n, maybe stand-alone?

I just want to read Laminas i18n Config Provider from an array formatted file and setup automatically instead of doing it in Config Aggregator manually as below.

     $aggregator = new ConfigAggregator(
            [
                new PhpFileProvider(getcwd().'/config/autoload/*.php'),
               'Laminas\I18n\ConfigProvider'
            ]
        );

Thanks.

After adding the Config Listener class is working right now.

require 'vendor/autoload.php';

use Laminas\EventManager\EventManager;
use Laminas\ModuleManager;
use Laminas\ModuleManager\Listener\{
	ListenerOptions,
	DefaultListenerAggregate
};
use Laminas\ServiceManager\ServiceManager;
use Laminas\ModuleManager\ModuleEvent;
use Laminas\ModuleManager\Listener\ServiceListener;
use Laminas\ModuleManager\Listener\ConfigListener;

$container = new ServiceManager;
$container->setFactory(Laminas\Config\Config::class, 'App\Factory\ConfigFactory');
$container->setAlias('config', Laminas\Config\Config::class);
$container->setService('ServiceListener', new ServiceListener($container));
$config = $container->get('config');
$serviceListener = $container->get('ServiceListener');

// https://github.com/laminas/laminas-mvc/blob/master/src/Service/ModuleManagerFactory.php
//
$serviceListener->addServiceManager(
    $container,
    'service_manager',
    'Laminas\ModuleManager\Feature\ServiceProviderInterface',
    'getServiceConfig'
);
$events = new EventManager;
$listenerOptions  = new ListenerOptions($config['module_listener_options']);
$defaultListeners = new DefaultListenerAggregate($listenerOptions);
$serviceListener  = $container->get('ServiceListener');
$configListener   = new ConfigListener($listenerOptions);
$defaultListeners->attach($events);
$serviceListener->attach($events);
$configListener->attach($events);

$moduleEvent = new ModuleEvent;
$moduleEvent->setParam('ServiceManager', $container);
$moduleEvent->setConfigListener($configListener);

$moduleManager = new ModuleManager\ModuleManager([
    'Laminas\I18n',
], $events);
$moduleManager->setEvent($moduleEvent);
$moduleManager->loadModules();
$module = $moduleManager->getModule('Laminas\I18n');

$config = $configListener->getMergedConfig();
echo '<pre>'.print_r($config->toArray(), true).'</pre>';