symfonyのプラグインコマンドのインストール先ディレクトリを変更する

Twitter@okonomiさんから以下の発言がありました。

symfonyでEthnaのpear-local的なことはできるんかな。手動でパッケージ管理とか無理ですよ? *Tw*

「symfony plugin:install -c pear.php.net --force-license -d pear」でPEARをインストールできた *Tw*

@hidenorigoto symfony plugin:install でいけました。ただふつうのプラグインと混じってしまうので、インストールディレクトリを指定できればよかったんですが分からなかったです。

これについて調べてみました。

プラグインのインストール先ディレクトリはsfBaseTask::getPluginManager()内で設定されている

がオプションなどでは変更できません

http://trac.symfony-project.org/browser/branches/1.4/lib/task/sfBaseTask.class.php#L361

<?php
361	  protected function getPluginManager()
362	  {
363	    if (null === $this->pluginManager)
364	    {
365	      $environment = new sfPearEnvironment($this->dispatcher, array(
366	        'plugin_dir' => sfConfig::get('sf_plugins_dir'),
367	        'cache_dir'  => sfConfig::get('sf_cache_dir').'/.pear',
368	        'web_dir'    => sfConfig::get('sf_web_dir'),
369	        'config_dir' => sfConfig::get('sf_config_dir'),
370	      ));

getPluginManager()メソッド内でsfPearEnvironmentを初期化しており、コンストラクタの引数を直接ここで指定しています。
このインストール先の設定を上手く変更してやればよさそうです。

以下では、「(project)/plugins2」ディレクトリにpearパッケージをインストールするタスクを作成します。

準備1:plugins2ディレクトリをオートロード対象に追加

/config/autoload.ymlファイルを作成し、以下のように記述します。

autoload:
  # plugins2
  plugins2:
    name:           plugins2
    path:           %SF_ROOT_DIR%/plugins2
    recursive:      true

準備2:カスタムプラグインマネージャークラス

/lib/myPluginManager.class.php

<?php
class myPluginManager extends sfSymfonyPluginManager
{
  public function listenToPluginPostInstall($event)
  {
    $this->installWebContent($event['plugin'], isset($event['plugin_dir']) ? $event['plugin_dir'] : $this->environment->getOption('plugin_dir'));

    //$this->enablePlugin($event['plugin'], $this->environment->getOption('config_dir'));
  }
}

デフォルトのプラグインマネージャーでは、プラグインのインストール後にProjectConfigurationのsetup()メソッドにenablePlugin()の記述が自動的に追加されます。
プラグインのインストール完了イベントで上記メソッドが呼び出されます)
この追加処理のみを無効にしたカスタムプラグインマネージャーを作成しています。

このファイルを作成後、symfony ccを実行してください。

準備3:plugin:install2タスクの作成

/lib/task/sfPluginInstall2Task.class.php

<?php
class sfPluginInstall2Task extends sfPluginInstallTask
{
  protected function configure()
  {
    parent::configure();
    $this->name = 'install2';
  }

  protected function getPluginManager()
  {
    if (null === $this->pluginManager)
    {
      $environment = new sfPearEnvironment($this->dispatcher, array(
        'plugin_dir' => sfConfig::get('sf_root_dir') . '/plugins2',
        'cache_dir'  => sfConfig::get('sf_cache_dir').'/.pear',
        'web_dir'    => sfConfig::get('sf_web_dir'),
        'config_dir' => sfConfig::get('sf_config_dir'),
      ));

      $this->pluginManager = new myPluginManager($this->dispatcher, $environment);
    }

    return $this->pluginManager;
  }
}

plugins2ディレクトリにインストールする専用のタスク「plugin:install2」です。
sfPluginInstallTaskとほぼ同じ処理なのでこのクラスを継承し、configure()メソッドで名前のみ変更します。

また、プラグインマネージャを取得するメソッドをオーバーライドして、インストール先ディレクトリと、プラグインマネージャークラスを変更しています。

plugin:install2を使用してpearをインストール

symfony plugin:install2 -c pear.php.net --force-license -d pear

のようにすれば、無事plugins2ディレクトリにpearパッケージがインストールされます。


ほぼ同じようにplugin:uninstall→plugin:uninstall2、plugin:list→plugin:list2なども作っておくと楽かもしれません。


P.S.
もう少しがんばれば、pear-local的なプラグインに仕上がると思いますが・・・・