symfonyの設定ファイルのカスケードルール

symfonyの設定ファイルは「カスケード」機能があって、下位のレベルに配置した設定ファイルで上位の設定を上書きしたりできます。
基本的な説明は、公式サイトの以下のページを参照してください。

基本ルールは「symfonyの初期設定」→「プロジェクトグローバル」→「アプリケーション」→「モジュール」と上書きされていくのですが、ここに「プラグイン」が入ると多少ややこしくなります。

プラグインも含めた設定ファイルのカスケードルール

symfonyプラグインを作成・インストールした場合、有効になっているプラグインのconfigディレクトリにある設定ファイルも自動読み込みの対象になります(config_handlers.ymlで設定しているもの)。
この場合のカスケードルールについては、sfApplicationConfigration::getConfigPaths()メソッドの以下の部分を見ると分かります。

<?php
public function getConfigPaths($configPath)
{
  $globalConfigPath = basename(dirname($configPath)).'/'.basename($configPath);

  $files = array(
    $this->getSymfonyLibDir().'/config/'.$globalConfigPath, // symfony
  );

  foreach ($this->getPluginPaths() as $path)
  {
    if (is_file($file = $path.'/'.$globalConfigPath))
    {
      $files[] = $file;                                     // plugins
    }
  }

  $files = array_merge($files, array(
    $this->getRootDir().'/'.$globalConfigPath,              // project
    $this->getRootDir().'/'.$configPath,                    // project
    sfConfig::get('sf_app_dir').'/'.$globalConfigPath,      // application
    sfConfig::get('sf_app_cache_dir').'/'.$configPath,      // generated modules
  ));

  foreach ($this->getPluginPaths() as $path)
  {
    if (is_file($file = $path.'/'.$configPath))
    {
      $files[] = $file;                                     // plugins
    }
  }

  $files[] = sfConfig::get('sf_app_dir').'/'.$configPath;   // module

  $configs = array();
  foreach (array_unique($files) as $file)
  {
    if (is_readable($file))
    {
      $configs[] = $file;
    }
  }

  return $configs;
}

このコードを読むと、特定の名前の設定ファイルに対して、以下の順番で各設定ファイルを読み込んでいることが分かります。

  1. symfonyライブラリの初期値(symfony/lib/config/config/hoge.yml)
  2. すべてのプラグインのグローバルconfig(プラグイン/config/hoge.yml)
  3. プロジェクトのグローバルconfig(プロジェクトルート/config/hoge.yml)
  4. プロジェクト直下の対象パスのconfig(プロジェクトルート/(パス)/hoge.yml)
  5. アプリケーションのグローバルconfig(アプリケーション/config/hoge.yml)
  6. アプリケーションキャッシュ直下の対象パスのconfig(アプリケーションキャッシュ/(パス)/hoge.yml)
  7. すべてのプラグインの対象パスのconfig(プラグイン/(パス)/hoge.yml)
  8. アプリケーション直下の対象パスのconfig(アプリケーション/(パス)/hoge.yml)

ここで、「グローバルconfig」とは、「config/hoge.yml」というパスのもので、「対象パスのconfig」というのは、主に「modules/(モジュール名)/config/hoge.yml」を指します。

OpenPNE3でのカスケード

OpenPNE3では、opApplicationConfigrationクラスがsfApplicationConfigrationクラスを継承しており、上記のsymfonyの設定ファイルカスケードの仕組みはそのまま引き継いでいます。

ただし、symfony側の設定ファイル列挙処理の後にOpenPNE側の設定ファイル列挙処理が追加される形になっています。これは、OpenPNE3では通常のapps配下は「コア」であり、その設定をプラグインで拡張するという優先順位になっているためです。

  1. symfony側の設定ファイル列挙処理
  2. OpenPNE/lib/config/config配下の設定ファイル
  3. すべてのプラグインのグローバルconfig(プラグイン/config/hoge.yml)
  4. すべてのプラグインの対象パスのconfig(プラグイン/(パス)/hoge.yml)
  5. すべてのプラグインの対象アプリケーション配下のグローバルconfig(プラグイン/apps/(アプリケーション)/config/hoge.yml)
  6. すべてのプラグインの対象アプリケーション配下の対象パスのconfig(プラグイン/apps/(アプリケーション)/(パス)/hoge.yml)