4

おそらく、generate:bundleコマンド(バンドルを生成した後、AppKernelを更新するように求めるプロンプトを表示する)またはComposer(インストールする依存関係でオートロードを更新する)に似ています。

generate:bundleと同様の機能を取得したいのですが、新しいバンドルを作成する代わりに、AppKernelを手動で編集せずに、ダウンロードしたばかりのバンドルを追加したいと思います。

4

3 に答える 3

4

既存のコマンドを拡張する方法が見つからなかったので、既存のバンドルに新しいコンソールコマンドを作成することを考えました。

namespace Your\OriginalBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class AppendNewBundleCommand extends ContainerAwareCommand
{
    protected $appKernel;

    protected function configure()
    {
        $this
            ->setName('yourbundle:appendnewbundle')
            ->setDescription('Append a new bundle to the AppKernel.php')
            ->addArgument('namespace', InputArgument::REQUIRED, 'Define your new bundle/namespace')
        ;
        $this->appKernel = __DIR__.'/../../../../app/AppKernel.php';
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        if (!file_exists($this->appKernel)) {
            throw new \ErrorException(sprintf("Could not locate file %s",$this->appKernel));
        }
        if (!is_writable($this->appKernel)) {
            throw new \ErrorException(sprintf('Cannot write into AppKernel (%s)',$this->appKernel));
        }

        $namespace = $input->getArgument('namespace');
        $appContent = file_get_contents($this->appKernel);

        $bundle = str_replace("/","\\",$namespace)."\\".str_replace("/","",$namespace);
        $newBundle = "new {$bundle}(),";

        $pattern = '/\$bundles\s?=\s?array\((.*?)\);/is';
        preg_match($pattern, $appContent,$matches);

        $bList = rtrim($matches[1],"\n ");
        $e = explode(",",$bList);
        $firstBundle = array_shift($e);
        $tabs = substr_count($firstBundle,'    ');

        $newBList = "\$bundles = array("
                            .$bList."\n"
                            .str_repeat('    ', $tabs).$newBundle."\n"
                        .str_repeat('    ',$tabs-1).");";

        file_put_contents($this->appKernel,preg_replace($pattern,$newBList,$appContent));
    }
}

これで、バンドルを生成した直後に実行できます。

php app/console yourbundle:appendnewbundle Your/SecondBundle

これにより、これが既存のバンドルのリストに追加されます

new Your\SecondBundle\YourSecondBundle(),

これは、標準(symfony2)のAppKernelがある場合に機能します。元:

<?php

use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
            new Symfony\Bundle\SecurityBundle\SecurityBundle(),
            new Symfony\Bundle\TwigBundle\TwigBundle(),
            new Symfony\Bundle\MonologBundle\MonologBundle(),
            new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
            new Symfony\Bundle\DoctrineBundle\DoctrineBundle(),
            new Symfony\Bundle\AsseticBundle\AsseticBundle(),
            new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
            new JMS\SecurityExtraBundle\JMSSecurityExtraBundle(),
            new Ornicar\ApcBundle\OrnicarApcBundle(),
            new Your\OriginalBundle\YourOriginalBundle(),
        );

        if (in_array($this->getEnvironment(), array('dev', 'test'))) {
            $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
            $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
            $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
        }

        return $bundles;
    }

    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
    }
}
于 2012-10-26T07:54:59.047 に答える
2

私はそれをテストしていません

use Symfony\Component\HttpKernel\KernelInterface;
use Sensio\Bundle\GeneratorBundle\Manipulator\KernelManipulator;
use RuntimeException;

class SomeClass {
    /**
     * Register bundle in Kernel
     * @param  KernelInterface $kernel
     * @param  sting           $namespace
     * @param  sting           $bundle
     * @return boolean
     * @throws RuntimeException         When bundle already defined in <comment>AppKernel::registerBundles()</comment>
     */
    protected function registerBundle(KernelInterface $kernel, $namespace, $bundle)
    {
        $manip = new KernelManipulator($kernel);

        return $manip->addBundle($namespace.'\\'.$bundle);
    }
}
于 2015-02-13T08:27:02.630 に答える
-2

技術的にはもちろん可能です、誰かがそれをしなければなりません。

于 2012-10-26T07:28:50.173 に答える