在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