Symfony 4 DependencyInjection编译器密码

时间:2018-09-29 14:56:16

标签: php dependency-injection definition symfony4

在Symfony 4中,我尝试使用CompilerPasses添加Admin MenuItems。例如,我上了仪表板课 这是一个MenuItem

仪表板(菜单项)

#src/Menu/MenuItems/

/**
 * Dashboard
 */

namespace App\Menu\MenuItems;

use App\Menu\MenuItem;

class Dashboard extends MenuItem
{
    const KEY = 'dashboard.menu.item';

    public function getKey(): string
    {
        return static::KEY;
    }

    /**
     * Init menu item
     *
     * @return MenuItem
     */
    public function init(): MenuItem
    {
       $this->setName('Dashboard');
       $path = $this->router->generate('dashboard');

       $this->setPath($path);

       return $this;
    }
}

我已经在内核中注册了名为AdminMenuItemCompilerPass的CompilerPass。此编译器遍历扫描MenuItems目录,并将MenuItems作为服务添加到容器中。

AdminMenuItemCompilerPass

#scr/DependencyInjection/Compiler/

/**
 * AdminMenuItemCompilerPass
 */

namespace App\DependencyInjection\Compiler;

use App\Menu\AdminMenu;
use App\Menu\MenuItem;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;

/**
 * Class AdminMenuItemCompilerPass
 */
class AdminMenuItemCompilerPass implements CompilerPassInterface
{
    const BHAM_ADMIN_MENU_ITEMS = 'bham.admin.menu.item';

    /**
     * @var string
     */
    private $srcDir;

    public function __construct(string $srcDir)
    {
        $this->srcDir = $srcDir;
    }

    /**
     * You can modify the container here before it is dumped to PHP code.
     * @param ContainerBuilder $container
     * @param string $namespace
     */
    public function process(ContainerBuilder $container, $namespace = 'App'): void
    {
        $component = 'Menu/MenuItems';
        $fs = new Filesystem();

        if ($fs->exists($path = $this->srcDir . $component)) {
            $finder = new Finder();
            /** @var SplFileInfo $file */
            foreach ($finder->files()->in($path)->depth('0') as $file) {
                $class = str_replace('/', '\\', $namespace . '/' .$component . '/' . str_replace('.php', '', $file->getFilename()));

                $definition = $container->hasDefinition($class) ? $container->getDefinition($class) : new Definition($class);

                $definition->setPublic(true);
                $definition->setAutowired(true);
                $definition->addTag(static::BHAM_ADMIN_MENU_ITEMS);

                // how to get menu item key here eq: Dashboard::KEY (dashboard.menu.item) ??
                $definition->addTag('HOW_TO_GET_MENU_ITEM_KEY_HERE??');

                $container->setDefinition($class, $definition);
            }
        }
    }
}

在功能过程中,我遍历了所有MenuItem,但是如何到达KEY并将其用作标记?

我已经在AdminMenuItemCompilerPass中尝试了以下操作

public function process(ContainerBuilder $container, $namespace = 'App'): void
            {
                $component = 'Menu/MenuItems';
                $fs = new Filesystem();

                if ($fs->exists($path = $this->srcDir . $component)) {
                    $finder = new Finder();
                    /** @var SplFileInfo $file */
                    foreach ($finder->files()->in($path)->depth('0') as $file) {
                        $class = str_replace('/', '\\', $namespace . '/' .$component . '/' . str_replace('.php', '', $file->getFilename()));


                        $definition = $container->hasDefinition($class) ? $container->getDefinition($class) : new Definition($class);

                        $definition->setPublic(true);
                        $definition->setAutowired(true);
                        $definition->addTag(static::BHAM_ADMIN_MENU_ITEMS);

                        // not working
                        $action = 'getKey';

                        if (is_callable(array($definition->getClass(), $action))) {
                            $callMethod = call_user_func(array($definition->getClass(), $action)); // not working
                            $callMethod = call_user_func(array(new Reference($definition->getClass()), $action)); // not working
                        }
... rest goes here

0 个答案:

没有答案