Drupal → Препроцессинг настроек форматтера перед сохранением

25.06.2024

У форматтеров есть метод settingsForm(), который генерит форму настроек форматтера, но нет метода settingsFormSubmit(), в котором можно было бы изменить эти настройки перед сохранением. Выходим из ситуации с помощью #element_validate:

class ExampleFormatter extends FormatterBase {

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings(): array {
    return [
      'example_setting_array' => [],
    ] + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state): array {
    $elements['example_setting_array'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Example setting array'),
      '#default_value' => implode("\n", $this->getSetting('example_setting_array')),
      '#element_validate' => [[$this, 'settingsFormExampleSettingArrayValidate']],
    ];

    return $elements;
  }

  /**
   * #element_validate callback for 'example_setting_array' element.
   */
  public function settingsFormExampleSettingArrayValidate(array $element, FormStateInterface $form_state): void {
    // Get value from request
    $value = $form_state->getValue($element['#parents']);
    // Change value
    $value = explode("\n", $value);
    // Update value in $form_state
    $form_state->setValueForElement($element, $value);
  }
  
  ...
}

Если нужно препроцессить много элементов, то можно навесить '#element_validate' на $elements:

  public function settingsForm(array $form, FormStateInterface $form_state): array {
    $elements['example_setting_array'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Example setting array'),
      '#default_value' => implode("\n", $this->getSetting('example_setting_array')),
    ];
    
    $elements['#element_validate'][] = [$this, 'settingsFormValidate'];

    return $elements;
  }
  
  public function settingsFormValidate(array $element, FormStateInterface $form_state): void {
    $values = $form_state->getValue($element['#parents']);
    $values['example_setting_array'] = explode("\n", $values['example_setting_array']);
    $form_state->setValueForElement($element, $values);
  }

Есть ещё вариант с $elements['example_setting_array']['#value_callback'], но там надо помнить, что #value_callback у элемента уже может быть, причём как собственный, так и установленный другим модулем.

Написанное актуально для
Drupal 8+
Похожие записи

Комментарии

Александр
28.06.2024, 10:02

А почему не через свойство #submit? Кажется, что #element_validate должен использоваться для валидации, а не изменения значений.

#submit чего? settingsForm() возвращает подформу, там нет доступа к основной форме.

Добавить комментарий