設定オーバーライドシステム
Drupal 8の設定システムは、設定を統一的に処理します。デフォルトでは、Drupalは設定データをデータベースに保存しますが、YAMLファイルにエクスポートして、バージョン管理で設定を管理できます。ただし、特定の目的のために設定値をオーバーライドする必要がある場合があります。Drupal 7では、settings.phpで設定の条件付きオーバーライド値で通常埋められるグローバル変数$confがありました。このシステムの大きな欠点は、オーバーライドが実際の設定に移行したことでした。オーバーライドされた値を含む設定フォームが保存されると、条件付きオーバーライドが実際の設定ストレージに入りました。
Drupal 8には、次のような設定オーバーライドシステムが導入されています:
- これらのオーバーライドを標準設定値の上の一時的なレイヤーとしてサポートする
- 設定フォームにオーバーライドされた値を使用しない
- ステージングとバージョン管理をサポートするために、オーバーライドを他の設定ファイルと一緒に保存できる(たとえば、言語オーバーライドの場合。下記参照)。
Drupal 7のグローバル変数$confは、Drupal 8では$configに名前が変更され、デフォルトの設定システムで有効になっています。
グローバルオーバーライド
Drupal 8は、グローバル$configの使用機能を維持しています。設定システムは、Drupal\Core\Config\ConfigFactory::get()の実装を通じてこれらのオーバーライド値をマージします。設定から値を取得すると、グローバル変数$configが戻り値を変更する機会を得ます:
// Get system site maintenance message text. This value may be overriden by
// default from global $config (as well as translations, see below).
$message = \Drupal::config('system.maintenance')->get('message');
たとえばsettings.phpでグローバル$configの設定値をオーバーライドするには、設定キーを参照します:
$config['system.maintenance']['message'] = 'Sorry, our site is down now.';
ネストされた値には、ネストされた配列キーを使用します
$config['system.performance']['css']['preprocess'] = 0;
$configをsettings.phpファイルの外で使用する場合は、前述のグローバル$configを使用してください;
利用可能な設定変数を次のいずれかの方法で確認すると役立つ場合があります:
- 「Configuration Manager」モジュールを使用して、/admin/config/development/configuration/single/exportにあるユーザーインターフェースから表示する
- サイトのYML設定ファイルを直接確認する、
- またはdrushを使用してクエリを実行する。
drush config-list
drush config-get system.performance --include-overridden
settings.phpで$configを使用してオーバーライドされた値は、Drupalの管理インターフェースから表示できないことに注意してください(#2408549:設定フォームがオーバーライドされた値を固定したかどうかを示さないまで、Configuration Override WarnまたはConfig Override Inspectorを使用できる場合を除く)。また、--include-overriddenフラグを追加しない限り、drushでの検査からも表示できません。管理インターフェースは設定に保存された値を表示するため、オーバーライドのない他の環境に変更を加えることができます。
セキュリティ上の理由でAPIキーをオーバーライドする例については、次を参照してください:Commerce Gateway支払いAPIキーのオーバーライド
オーバーライドを回避する
オーバーライドなしで設定を取得して、元の設定値にアクセスできます(たとえば、グローバルオーバーライドの適用も無効にする場合など)。これは、たとえば設定フォームを作成している場合に非常に役立ちます。フォームにはオーバーライドなしの環境を使用することが重要です。これにより、値が保存された設定に入り込むのを防げます。コードが多言語環境で使用されている場合(設定値が通常翻訳としてオーバーライドされる場合)、これはさらに役立ちます。
オーバーライドありとなしで設定を取得する例をいくつか示します。
// Get the site name, with overrides.
$site_name = \Drupal::config('system.site')->get('name');
// Get the site name without overrides.
$site_name = \Drupal::config('system.site')->getOriginal('name', FALSE);
// Note that mutable config is always override free.
$site_name = \Drupal::configFactory()->getEditable('system.site')->get('name');
config.storageサービス(StorageInterface::read()を実装)を介して設定ストレージに直接アクセスすることもできます。ただし、これは設定にアクセスする正しい方法であることはめったにありません。
言語オーバーライド
たとえば、ユーザーに電子メールを送信する場合、その設定はページの言語ではなくユーザーの言語である必要があります。以前使用した言語を記憶し、ユーザーに応じて正しい言語を設定し、設定に基づいて操作を実行し、言語を元に戻します:
// Load the language_manager service
$language_manager = \Drupal::service('language_manager');
// Get the target language object
$langcode = $account->getPreferredLangcode();
$language = $language_manager->getLanguage($langcode);
// Remember original language before this operation.
$original_language = $language_manager->getConfigOverrideLanguage();
// Set the translation target language on the configuration factory.
$language_manager->setConfigOverrideLanguage($language);
$mail_config = \Drupal::config('user.mail');
// Now send email based on $mail_config which is in the proper language.
// Set the configuration language back.
$language_manager->setConfigOverrideLanguage($original_language);
言語オーバーライドシステムも、設定ストレージを使用してオーバーライドを保存します($configベースのグローバルオーバーライドとは異なります)。言語オーバーライドは、基本ファイルにちなんで名付けられたファイルに保存されます。したがって、上記のuser.mail設定ファイルに特定の言語のオーバーライドが存在する場合、それはlanguage.config.$langcode.user.mailと呼ばれます。オーバーライドファイルは、language.config.プレフィックス、その後に言語コード、その後に元の設定キーという順序で名前が付けられます。ファイルを通常の設定と一緒に保存することで、設定の段階的な翻訳が可能になり、基本設定と同様に変更できます。
これらの言語オーバーライドファイルはどのようにして最初に作成されるのでしょうか?ロケールモジュールはシステムイベントと統合して、設定スキーマ情報に基づいて提供される設定の翻訳ファイルを作成します。また、スキーマに基づいて設定を翻訳するための一般的なユーザーインターフェースを提供するコア設定翻訳モジュールもあります。これは、提供される設定とユーザー設定の両方で機能し、同じ言語オーバーライドファイルで機能します。
モジュールからのオーバーライドの提供
モジュールレベルでのオーバーライドは、任意のモジュールから提供することもできます。Drupalコアはグローバルオーバーライドと言語ベースのオーバーライドをサポートしていますが、ユーザーロールベース、コンテキストベース、ドメインベース、グループベースなど、他の多くの種類のオーバーライドのユースケースがあります。モジュールは、これらのオーバーライドを実行するための独自の基準を定義できます。
ConfigFactoryがモジュール提供のオーバーライドを収集するとき、config.factory.overrideとしてタグ付けされたすべてのサービスを呼び出します:
config_example.services.yml
services:
config_example.overrider:
class: Drupal\config_example\Config\ConfigExampleOverrides
tags:
- {name: config.factory.override, priority: 5}
サブスクライバーの優先度を設定して、オーバーライドの優先順位を指定します。優先度の高いオーバーライドは、優先度の低いオーバーライドより優先されます(同じ設定名の場合)。
src/Config/ConfigExampleOverrides.php
namespace Drupal\config_example\Config;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
use Drupal\Core\Config\StorageInterface;
/**
* Example configuration override.
*/
class ConfigExampleOverrides implements ConfigFactoryOverrideInterface {
/**
* {@inheritdoc}
*/
public function loadOverrides($names) {
$overrides = array();
if (in_array('system.site', $names)) {
$overrides['system.site'] = ['name' => 'Overridden site name!'];
}
return $overrides;
}
/**
* {@inheritdoc}
*/
public function getCacheSuffix() {
return 'ConfigExampleOverrider';
}
/**
* {@inheritdoc}
*/
public function getCacheableMetadata($name) {
return new CacheableMetadata();
}
/**
* {@inheritdoc}
*/
public function createConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) {
return NULL;
}
}
設定オーバーライド自体は、language、modules、settings.phpの3つの異なるレベルで機能し、最後のものが優先されます。settings.phpファイルのオーバーライドは、モジュールによって提供される値より優先されます。モジュールによって提供されるオーバーライドは、言語より優先されます。モジュールのオーバーライドのイベントサブスクライバーの優先度は、他のモジュールのオーバーライドに対する優先度のみを設定します。言語またはsettings.phpのオーバーライドに対してより高い優先度を設定するために使用することはできません。
Drupalコアの設定フォームは、オーバーライドされた設定値を使用しないことに注意してください。上記のモジュールオーバーライドの例では、/admin/config/system/site-informationに「Overridden site name!」は表示されません。
オーバーライド内で元の設定値を読み取る必要がある場合(たとえば、比較またはマージのため)、オーバーライド内の無限ループを回避するために、\Drupal::configではなく\Drupal::configFactoryからロードする必要があることを繰り返しておきます:
$original = \Drupal::configFactory()->getEditable('system.site')->getOriginal('name', FALSE);
さらに詳しい情報
オーバーライドシステムは、最新/現在の形式で#2098119:configコンテキストシステムを、ロケールと単一イベントベースのオーバーライドの組み込みサポートに置き換えるで追加されました。
履歴/レガシー情報については、#1646580:ローカライズされた設定のための設定イベントとリスナー、ストレージ領域を実装する(設定オーバーライドシステムが最初に導入された場所)と#1763640:コンテキストアクセスで機能するように大幅に変更された設定コンテキストを導入して、元の設定と他のオーバーライドを利用可能にするを参照してください。言語固有のオーバーライドは、#2020361:言語ベースの設定オーバーライドを有効にするLanguageConfigContextを作成するで後で追加されました。