2012-10-26 44 views
4

也許類似於generate:bundle命令(在生成包後會提示更新AppKernel)或Composer(它會使用您安裝的依賴關係更新自動加載)。有沒有辦法自動更新symfony2中的AppKernel?

我想獲得與generate:bundle類似的功能,但不是創建一個新的bundle,而是我想添加一個我剛剛下載的bundle,而無需手動編輯AppKernel。

回答

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'); 
    } 
} 
+0

感謝。我正要做這樣的事情。我打算將現有的generate:bundle代碼中的代碼複製到單獨的命令中。 – Jens

+1

酷!這個命令應該包含在Symfony框架中。 – caligari

+0

哇! +1的努力,但-1000爲你在那裏做什麼!這是你的應用程序的核心!我不是故意冒犯,但有時候我們會爲了找到任何解決方案而感到失望(我也包括自己) - 但是我們忘記檢查我們獲得的小優勢(自動添加一行代碼)是不是實際上會產生更多的問題。如果我們在這裏談論生成一個包 - 這肯定意味着會涉及到一些編碼 - 在內核中手動添加一行並不是一件很大的工作。 – jakabadambalazs

-2

從技術上講,這當然是可能的,有人只需要這樣做。

1

我還沒有測試它

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); 
    } 
} 
相關問題