Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 - Access kernel from a compiler pass

Is there a way to access the kernel from inside a compiler pass? I've tried this:

    ...
    public function process(ContainerBuilder $container)
    {
        $kernel = $container->get('kernel');
    }
    ...

This throws an error. Is there another way to do it?

like image 551
orourkedd Avatar asked Dec 13 '12 03:12

orourkedd


2 Answers

As far as I can tell, Kernel isn't available anywhere in a CompilerPass, by default.

But you can add it in by doing this:

In your AppKernel, pass $this to the bundle the compiler pass is in.

  • Add a constructor to your Bundle object, which accepts the Kernel as a parameter and stores it as a property.
  • In your Bundle::build() function, pass the Kernel to your CompilerPass instance.
  • In your CompilerPass, at a constructor to accept the Kernel as a parameter and store it as a property.
  • Then you can use $this->kernel in your compiler pass.

// app/AppKernel.php
new My\Bundle($this);

// My\Bundle\MyBundle.php
use Symfony\Component\HttpKernel\KernelInterface;

class MyBundle extends Bundle {
protected $kernel;

public function __construct(KernelInterface $kernel)
{
  $this->kernel = $kernel;
}

public function build(ContainerBuilder $container)
{
    parent::build($container);
    $container->addCompilerPass(new MyCompilerPass($this->kernel));
}

// My\Bundle\DependencyInjection\MyCompilerPass.php
use Symfony\Component\HttpKernel\KernelInterface;

class MyCompilerPass implements CompilerPassInterface
protected $kernel;

public function __construct(KernelInterface $kernel)
{
   $this->kernel = $kernel;
}

public function process(ContainerBuilder $container)
{
    // Do something with $this->kernel
}
like image 62
samanime Avatar answered Oct 17 '22 16:10

samanime


What samanime recommends works if you need to whole kernel.

If you are just interested in some values the kernel contains, it might be sufficient to just use the parameters set by symfony.

Here is a list of available ones:

Array
(
    [0] => kernel.root_dir
    [1] => kernel.environment
    [2] => kernel.debug
    [3] => kernel.name
    [4] => kernel.cache_dir
    [5] => kernel.logs_dir
    [6] => kernel.bundles
    [7] => kernel.charset
    [8] => kernel.container_class
    [9] => kernel.secret
    [10] => kernel.http_method_override
    [11] => kernel.trusted_hosts
    [12] => kernel.trusted_proxies
    [13] => kernel.default_locale
)

For instance, the kernel.bundles contains a list of all registered bundles in the format [bundle => class].

PS: I fetched this list using the following compiler pass:

<?php
namespace Acme\InfoBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class InfoCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        print_r(array_values(array_filter(
            array_keys($container->getParameterBag()->all()), 
            function ($e) {
                return strpos($e, 'kernel') === 0;
            }
        )));
        die;
    }
}
like image 10
Yannick Avatar answered Oct 17 '22 16:10

Yannick