web-dev-qa-db-ja.com

構成APIで情報の配列を格納する適切な方法は何ですか?

Drupal 7でカスタムフォームと変数を使用すると、「変数」テーブルに情報の配列を簡単に保存できます。ユーザーロールごとに設定を提供する構成フォームを作成することもありました。次に、各ロールの設定を個別の変数に格納するか、すべての設定を1つの配列にパックしてそのように格納します。

Drupal 8.で同様のことを行うための標準的なベストプラクティスの方法は何でしょうか。

in Drupal 7私はフォームコードに対して次のようなものになるでしょう:

// build list of roles
  $user_roles = user_roles(TRUE);
  // remove authenticated user role from options
  if (isset($user_roles[2])) {
    unset($user_roles[2]);
  }
$role_settings = variable_get('MYMODULE_role_type_mapping', $role_settings);
foreach ($user_roles as $rid => $role) {
      $form['roles']['other_roles']['MYMODULE_role_' . $rid . '_type_mapping'] = [
        '#title'         => $role,
        '#type'          => 'select',
        '#options'       => $membership_types,
        '#default_value' => !empty($role_settings[$rid]) ? $role_settings[$rid] : '',
      ];
    }

そして、フォーム送信コールバックで次のようなもの:

    // build list of roles
      $user_roles = user_roles(TRUE);
      // remove authenticated user role from options
      if (isset($user_roles[2])) {
        unset($user_roles[2]);
      }
      foreach ($user_roles as $rid => $role) {
        $role_settings[$rid] = !empty($form_state['values']['MYMODULE_role_' . $rid . '_type_mapping']) ? $form_state['values']['MYMODULE_role_' . $rid . '_type_mapping'] : '';
      }
variable_set('MYMODULE_role_type_mapping', $role_settings);

このタイプは、カスタムモジュールを複数のサイトにインストールする場合に必要です。サイトごとに異なる数のロールが存在する可能性があります。

つまり、Drupal 8の場合、この新しい構成APIがあります。事前に役割を知っているとは思いません。

「シンプルな設定」でこれを実現したいと思っていましたが、カスタム設定エンティティを作成する必要があるかもしれませんが、それなしで実行できると、ニースで「シンプル」になります。

このリソースによると: https://www.drupal.org/node/1905070#types 構成フィールドのスキーマタイプはほんのわずかですが、この場合、直感的に適切なものはありません。

そのページを読むと、多値の選択リストの値を構成にどのように格納するのかさえ明らかではなく、さまざまな種類の情報の配列である可能性のある変数は言うまでもありません。 D7では、複数値の選択リストは配列を返します。 D7では、変数はシリアル化された変数として格納されます。 D7の「simple_settings_form」でさえ、これを問題なく処理します。

確かにこの種の問題は何度も解決されていますが、情報を見つけるのは「簡単」ではありません。

したがって、問題は2つあります。1)値の配列を構成に格納するだけで、配列要素の数は不明で、数はカスタムサイトの条件(サイトでのユーザーロールなど)に依存します。2)この配列を解凍してフォーム要素を設定します送信時に、すべてを1つの変数にパックします。

同様の質問、より簡単な質問は次のとおりです。複数値の選択リストの構成スキーマを定義している場合、どのデータ型を使用しますか?ストリング?

私がここでD7に使用したモデルはD8に移植可能ですが、おそらくより良い方法がいくつかありますが、サイトの各ロールの構成エンティティを作成することはすべて単純ではなく、可能な限り単純ではないようですD7で行われます。サイト間のエクスポート/インポートの設定を検討したいのですが。サイトのdev/staging/productionバージョンはすべて同じユーザーロールを持つ可能性がありますが、完全に別個のWebサイトではありません。

この投稿ではいくつか質問しますが、一般的なテーマは、情報の配列を構成として適切にDrupal 8?に保存する方法ですか?単純なケースは、複数値の選択リストの値であり、より複雑です私が説明するようなユーザーロールごとの設定のシナリオ。

前もって感謝します!

4
jackrabbithanna

スキーマタイプsequenceを定義します。

例:/ core/modules/options/config/schema/options.schema.yml

# Schema for the configuration files of the Options module.

field.storage_settings.list_integer:
  type: mapping
  label: 'List (integer) settings'
  mapping:
    allowed_values:
      type: sequence
      label: 'Allowed values list'
      sequence:
        type: mapping
        label: 'Allowed value with label'
        mapping:
          value:
            type: integer
            label: 'Value'
          label:
            type: label
            label: 'Label'

この例のフォームは/ core/modules/options/src/Plugin/Field/FieldType/ListItemBase.phpにあります

詳細情報 https://www.drupal.org/docs/8/api/configuration-api/configuration-schemametadata

7
4k4

文字列のネストされた配列でデータを格納する方法に最近苦労していました、

allowed_view_modes:
  image:
    embed: embed
    full: full

それを検証する方法を理解できる唯一の方法は、機能テストを実行することでした。構成テストは、構成エンティティを保存するときに構成を検証します。

「シーケンス」をネストすることで、上記のようなデータを保存することができました。

ckeditor.plugin.drupalmedia:
  type: mapping
  label: 'Media Embed'
  mapping:
    allowed_view_modes:
      type: sequence
      label: 'Allowed View Modes'
      nullable: true
      sequence:
        type: sequence
        nullable: true
        label: 'View Mode'
        sequence:
          type: string

これは機能し、構成リンターを渡しました。

最上位のシーケンスはメディアタイプ用で、内部のシーケンスは各表示モード用です。 drupalコアには多くの複雑な例があります。残念ながら、ドキュメントのどこを参照すればよいのかわかりません。私はこれを試行錯誤してほとんど学んでいます。

2
oknate

これは私が取り組んでいたカスタムのopenid_connectプラグインでしたので、ConfigFormBaseの通常の構成フォームとは少し異なりますが、この方法論が適用され、将来の誰かに役立つことを願っています。私はそのようなスキーマを使用しました(スニペット):

# Schema for the configuration files of the OpenID Connect module.
openid_connect.settings.nimble:
  type: config_object
  label: 'OpenID Connect Nimble settings'
  mapping:
    enabled:
      type: boolean
      label: 'Enable client'
    settings:
      type: mapping
      mapping:
        roles_membership_types:
        type: sequence
        label: 'Role Membership Types'
        sequence:
          type: mapping
          label: 'Roles mapped to membership types'
          mapping:
            role:
              type: string
              label: 'Role id'
            membership_type:
              type: string
              label: 'Membership Type'

そのようなFAPIセットアップ(構成アイテムの実際の名前(roles_membership_types:

    $roles = user_role_names(TRUE);
    if (isset($roles['authenticated'])) {
      unset($roles['authenticated']);
    }
    $membership_types = ['' => 'None'] + $this->getMembershipTypes($this->configuration['instance']);
    $roles_membership_types = $this->configuration['roles_membership_types'];
    if (!empty($roles_membership_types)) {
      foreach ($roles_membership_types as $type) {
        $roles_membership_types_default_values[$type['role']] = $type['membership_type'];
      }
    }
    foreach ($roles as $rid => $role) {
      $form['roles_mapped_membership_types'][$rid] = [
        '#title'         => $role,
        '#type'          => 'select',
        '#options'       => $membership_types,
        '#default_value' => !empty($roles_membership_types_default_values[$rid]) ? $roles_membership_types_default_values[$rid] : '',
      ];
    }

ロールフォーム要素から値を取得し、構成をマップするために必要な形式にまとめるための、送信ハンドラーの少しのコード。

$values = $form_state->getValues();
if (!empty($values['roles_mapped_membership_types'])) {
  foreach ($values['roles_mapped_membership_types'] as $rid => $membership_type) {
    $roles_to_membership_type_value[] = ['role' => $rid, 'membership_type' => $membership_type];
  }
$form_state->setValue('roles_membership_types', $roles_to_membership_type_value);
}

したがって、最終的にこのコードは機能します:

// Save plugin settings.
$this->configFactory()
  ->getEditable('openid_connect.settings.' . $plugin_id)
  ->set('settings', $subform_state->getValues())
  ->save();
2
jackrabbithanna