覆盖DependencyInjection或卸载XML / YML

时间:2017-03-23 14:17:19

标签: php symfony

我有mybundle来覆盖SonataMediaBundle,

所以,这是我的包

应用程序\奏\ MediaBundle \ DependencyInjection \ ApplicationSonataMediaExtension

FirebaseDatabase.getInstance().getReference().child("users)
                .orderByKey()
                .equalTo(token)

这是原始的DependancyInjection。 奏\ MediaBundle \ DependencyInjection \ SonataMediaExtension

class ApplicationSonataMediaExtension extends Extension
{
    /**
     * {@inheritDoc}
     */
    public function load(array $configs, ContainerBuilder $container)
    {
           $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));  
        $loader->load('myservice.xml'); 
    }

通常这种方式对我的服务来说已经足够了,但就我而言。

我想卸载原始DependancyInjection中加载的一些xml。

例如

class SonataMediaExtension extends Extension { /** * {@inheritdoc} */ public function load(array $configs, ContainerBuilder $container) { $processor = new Processor(); $configuration = new Configuration(); $config = $processor->processConfiguration($configuration, $configs); $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('provider.xml'); $loader->load('media.xml'); $loader->load('twig.xml'); $loader->load('security.xml'); $loader->load('extra.xml'); $loader->load('form.xml'); $loader->load('gaufrette.xml'); // NEXT_MAJOR: Remove Following lines $amazonS3Definition = $container->getDefinition('sonata.media.adapter.service.s3'); if (method_exists($amazonS3Definition, 'setFactory')) { $amazonS3Definition->setFactory(array('Aws\S3\S3Client', 'factory')); } else { $amazonS3Definition->setFactoryClass('Aws\S3\S3Client'); $amazonS3Definition->setFactoryMethod('factory'); } // NEXT_MAJOR: Remove Following lines $openCloudDefinition = $container->getDefinition('sonata.media.adapter.filesystem.opencloud.objectstore'); if (method_exists($openCloudDefinition, 'setFactory')) { $openCloudDefinition->setFactory(array(new Reference('sonata.media.adapter.filesystem.opencloud.connection'), 'ObjectStore')); } else { $openCloudDefinition->setFactoryService('sonata.media.adapter.filesystem.opencloud.connection'); $openCloudDefinition->setFactoryMethod('ObjectStore'); } $loader->load('validators.xml'); $loader->load('serializer.xml'); if (!in_array(strtolower($config['db_driver']), array('doctrine_orm', 'doctrine_mongodb', 'doctrine_phpcr'))) { throw new \InvalidArgumentException(sprintf('SonataMediaBundle - Invalid db driver "%s".', $config['db_driver'])); } $bundles = $container->getParameter('kernel.bundles'); if (isset($bundles['FOSRestBundle']) && isset($bundles['NelmioApiDocBundle'])) { $loader->load(sprintf('api_form_%s.xml', $config['db_driver'])); if ('doctrine_orm' == $config['db_driver']) { $loader->load('api_controllers.xml'); } } if (isset($bundles['SonataNotificationBundle'])) { $loader->load('consumer.xml'); } if (isset($bundles['SonataFormatterBundle'])) { $loader->load('formatter.xml'); } if (isset($bundles['SonataBlockBundle'])) { $loader->load('block.xml'); } if (isset($bundles['SonataSeoBundle'])) { $loader->load('seo_block.xml'); } if (!isset($bundles['LiipImagineBundle'])) { $container->removeDefinition('sonata.media.thumbnail.liip_imagine'); } if (!array_key_exists($config['default_context'], $config['contexts'])) { throw new \InvalidArgumentException(sprintf('SonataMediaBundle - Invalid default context : %s, available : %s', $config['default_context'], json_encode(array_keys($config['contexts'])))); } $loader->load(sprintf('%s.xml', $config['db_driver'])); if (isset($bundles['SonataAdminBundle'])) { $loader->load(sprintf('%s_admin.xml', $config['db_driver'])); } $this->configureFilesystemAdapter($container, $config); $this->configureCdnAdapter($container, $config); $pool = $container->getDefinition('sonata.media.pool'); $pool->replaceArgument(0, $config['default_context']); // this shameless hack is done in order to have one clean configuration // for adding formats .... $pool->addMethodCall('__hack__', $config); $strategies = array(); foreach ($config['contexts'] as $name => $settings) { $formats = array(); foreach ($settings['formats'] as $format => $value) { $formats[$name.'_'.$format] = $value; } $strategies[] = $settings['download']['strategy']; $pool->addMethodCall('addContext', array($name, $settings['providers'], $formats, $settings['download'])); } $container->setParameter('sonata.media.admin_format', $config['admin_format']); $strategies = array_unique($strategies); foreach ($strategies as $strategyId) { $pool->addMethodCall('addDownloadStrategy', array($strategyId, new Reference($strategyId))); } if ('doctrine_orm' == $config['db_driver']) { $this->registerDoctrineMapping($config); } $container->setParameter('sonata.media.resizer.simple.adapter.mode', $config['resizer']['simple']['mode']); $container->setParameter('sonata.media.resizer.square.adapter.mode', $config['resizer']['square']['mode']); $this->configureParameterClass($container, $config); $this->configureExtra($container, $config); $this->configureBuzz($container, $config); $this->configureProviders($container, $config); $this->configureAdapters($container, $config); $this->configureResizers($container, $config); $this->configureClassesToCompile(); } 以原始版本加载。

但是我不想让它加载。

我有两个想法

  1. 在我的包中卸载

  2. 覆盖(复制所有脚本)原始包并注释掉。但是如何覆盖???

  3. 我该怎么办?

    我想删除管理员的yml。 奏\ MediaBundle \ DependencyInjection \ SonataMediaExtension

    $loader->load('media.xml');

    这个问题与此有关 here

    感谢@dbrumann评论,我决定使用CompilerPass。

    我实施了

    在Acme \ AdminBundle \ AcmeAdminBundle

     if (isset($bundles['SonataAdminBundle'])) {
            $loader->load(sprintf('%s_admin.xml', $config['db_driver']));
        }
    

    在CustomPass中

    namespace Acme\AdminBundle;
    
    use Symfony\Component\HttpKernel\Bundle\Bundle;
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    use Acme\AdminBundle\DependencyInjection\Compiler\CustomPass;
    //use  \Symfony\Component\DependencyInjection\Compiler\PassConfig;
    
    class AcmeAdminBundle extends Bundle
    {
        public function build(ContainerBuilder $container)
        {
            parent::build($container);
    
            $container->addCompilerPass(new CustomPass());
        }
    

    看起来我向前迈进了一步。但是这个错误发生了。

    namespace Acme\AdminBundle\DependencyInjection\Compiler;
    
    use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    
    class CustomPass implements CompilerPassInterface {
        public function process(ContainerBuilder $container)
        {
            var_dump($container->getDefinitions());
            if ($container->hasDefinition('sonata.admin.arobject')) //I have arobject entity on dashboard
             {
               $container->removeDefinition('sonata.admin.arobject');
             }
        }
    }
    

    mysteriously [2/2] FileLoaderLoadException: You have requested a non-existent service "sonata.admin.arobject". Did you mean one of these: "sonata.admin.armarket", "sonata.admin.artracker", "sonata.admin.exporter", "sonata.admin.helper", "sonata.admin.placecat", "sonata.admin.pool", "sonata.admin.user"? in . (which is being imported from "/Users/whitebear/CodingWorks/httproot/arserver/app/config/routing.yml"). 返回true,但是,$container->hasDefinition('sonata.admin.arobject')会返回上面的错误。

    这是我的var_dump($ container-> getDefinitions()){{3}}

    最后我发现有两种方法可以解决这个问题。

    1)使用CompilerPass

    2)加载新的service.xml

    如果您无法从管理信息中心删除mediabundle和classificationbundle。

    请检查{{3}}

1 个答案:

答案 0 :(得分:1)

你试图做的事听起来非常危险。我对SonataAdminBundle不是很熟悉,但是当捆绑包使用提供的服务时,你会破坏它。也许您可以通过解释来解释为什么要卸载这些服务。

与此同时,您可能需要结帐CompilerPasses。它们在容器构建之前运行并且可以改变它。你可以在ContainerBuilder上调用removeDefinition()来摆脱服务。您可以专门删除要删除的定义,而不是卸载服务。或者,您可以将其替换为其他服务或根据您的需要进行更改。