In a regular Symfony application or bundle a compiler pass for instance can be added
by calling $container->addCompilerPass()
inside the build()
function of the application’s
Kernel
or the bundle’s Bundle
class (see the Symfony documentation
for details). In fact this holds true for any modifications that need to be made to
the container at compile time.
In a typical Contao Managed Edition setup, we cannot alter the Kernel nor does the
application - following current best practices to be bundle-less - contain a
Bundle
class. However, we can also utilize the Contao Manager Plugin to alter the
container and thus also add compiler passes and other things there.
Make sure your plugin implements the ConfigPluginInterface
and implement the
registerContainerConfiguration
method (see Plugin documentation).
Now the provided loader allows accessing the container.
See this example on how to add a custom compiler pass:
// src/ContaoManager/Plugin.php
namespace App\ContaoManager;
use App\DependencyInjection\Compiler\MyCompilerPass;
use Contao\ManagerPlugin\Config\ConfigPluginInterface;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class Plugin implements ConfigPluginInterface
{
public function registerContainerConfiguration(LoaderInterface $loader, array $managerConfig)
{
$loader->load(static function (ContainerBuilder $container) {
$container->addCompilerPass(new MyCompilerPass());
});
}
}
This can be very useful for example to make certain services public, if you need to access them in
legacy code where you cannot use Dependency Injection yet and have to rely on Contao\System::getContainer()->get('<service.id>')
for that matter. Combined with anonymous classes, this could look like this:
// src/ContaoManager/Plugin.php
namespace App\ContaoManager;
use App\DependencyInjection\Compiler\MyCompilerPass;
use Contao\ManagerPlugin\Config\ConfigPluginInterface;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class Plugin implements ConfigPluginInterface
{
public function registerContainerConfiguration(LoaderInterface $loader, array $managerConfig)
{
$loader->load(static function (ContainerBuilder $container) {
$container->addCompilerPass(new class implements CompilerPassInterface {
public function process(ContainerBuilder $container)
{
// Example for making a custom monolog logger public
$container->getDefinition('monolog.logger.api')
->setPublic(true);
// Or the general "logger" alias
$container->getAlias('logger')
->setPublic(true);
}
});
});
}
}