Symfony2:自定义配置根目录

时间:2012-09-10 12:53:29

标签: php symfony

我的应用程序包含多个名为HelloWorldAdminBundleHelloWorldUserBundleHelloWorldDemoBundle的包。这会产生类似hello_world_demohello_world_userhello_world_demo的配置根。我希望我的捆绑包的配置根目录是helloworld_demohelloworld_userhelloworld_admin。那时我不得不提到这不是一个技术问题,而是一个美学问题。

我试图实现自定义扩展并在Bundle中注册它:

public function build(ContainerBuilder $container)
{
    parent::build($container);

    $container->registerExtension(new HelloworldDemoExtension());
}

扩展名:

...
class HelloworldDemoExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
        $loader->load('services.yml');
    }

    public function getAlias()
    {
        return 'hello_world_demo';
    }
}

最后是配置:

...
class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('helloworld_demo');
        ...
        return $treeBuilder;
    }
}

我按照说明How to expose a Semantic Configuration for a Bundle,但是当我向config.yml添加项目时,我收到以下错误:

There is no extension able to load the configuration for "helloworld_demo"

4 个答案:

答案 0 :(得分:3)

我找到了解决问题的方法。它完全按照我在问题中描述的那样工作,但是,默认扩展名(包含名称)必须

我现在有一个空的,但现有的扩展名为HelloWorldDemoExtension(别名为hello_world_demo,另外我添加了DemoExtension(别名为helloworld_demo)并且它可以正常工作。

答案 1 :(得分:3)

我通过覆盖Symfony\Component\HttpKernel\Bundle\Bundle#getContainerExtension()来解决这个问题。

此方法会自动创建并返回ExtensionInterface的实例,并检查扩展程序的别名(您可以在扩展类中实现getAlias指定,如Carlos Granados'所述)符合命名惯例。

因此,通过覆盖bundle类中的getContainerExtension()方法,并简单地返回扩展类的实例,您可以绕过检查和LogicException

这是你的bundle类的样子:

<?php

namespace HelloWorld\Bundle\UserBundle;

use HelloWorld\Bundle\UserBundle\DependencyInjection\HelloWorldUserExtension;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class HelloWorldUserBundle extends Bundle
{
    public function getContainerExtension()
    {
        if (null === $this->extension) {
            $this->extension = new HelloWorldUserExtension();
        }

        return $this->extension;
    }
}

当然,不要忘记将其添加到您的扩展程序中:

/**
 * The extension alias
 *
 * @return string
 */
public function getAlias()
{
    return 'helloworld_user';
}

警告:我不确定为何将此检查添加到getContainerExtension()方法中。可能有一个非常有效的原因,并且在执行上述步骤时可能会遇到问题。但是,到目前为止我没有遇到任何问题。

修改:另请参阅:Symfony2: Some things I don't like about Bundles。这篇博客文章提供了与我的答案相同的解决方案。另请参阅this pull request以获取Symfony的文档,该文档也描述了相同的方法。这让我相信这样做是安全的,而不必期待副作用。

答案 2 :(得分:0)

正如documentation所说:

  

创建扩展程序时,请遵循以下简单约定:

     
      
  • 扩展名必须存储在DependencyInjection子命名空间中;
  •   
  • 扩展名必须以包名称命名,并以Extension为后缀(AcmeHelloExtension for AcmeHelloBundle);
  •   
  • 扩展程序应提供XSD架构。
  •   

我真的不知道您是否需要定义自己的buildgetAlias方法。如果需要,那么getAlias方法应该返回与在根节点中定义的值相同的值。因此,它应该helloworld_demo而不是hello_world_demo

答案 3 :(得分:0)

从书中 “在这种情况下,扩展类还必须实现一个getAlias()方法,并返回一个以bundle命名的唯一别名(例如acme_hello)。这是必需的,因为类名不符合标准,以Extension结尾。 此外,只有当用户在至少一个配置文件中指定acme_hello别名时,才会调用扩展的load()方法。 “

所以,这个别名是根配置名称。将您的代码更改为

public function getAlias()
{
    return 'helloworld_demo';
}

它应该可行