web-dev-qa-db-ja.com

保存する直前にWebフォーム送信フィールドを変更するにはどうすればよいですか?

エンドユーザーがDrupal 8 Webフォームに入力されたデータを送信する場合、カスタムモジュールで同じフォームにあるフィールドを他のフィールドの値に基づいて変更します。送信されたデータの値にアクセスしたり、保存する前に変更したいフィールドの値を設定したりするのに問題があります。

フックのスターターを含むサンプルのwebform APIファイルが含まれています。役に立つかもしれないと思ったフックは以下です。

_function hook_webform_submission_form_alter(array &$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {}
_

これらの変数の値を出力するためにdpm()を使用しました。 _$form_state_変数にはデータが送信されており、保存する前に_$form_変数を使用してこれらの値を変更できることを知っています。

送信されたデータの値を取得し、送信が保存される前に同じページの別のフィールドの値を設定するにはどうすればよいですか? Drupal 7では、これはかなり簡単でしたが、Drupal 8では、変数の配列とオブジェクト構造のナビゲートはそれほど透過的ではありません。

7
Parag

ハンドラでpreSaveメソッドを使用できます。 Webformコードベースの一部であるWebformモジュールハンドラーテストモジュールを確認してください。すべてのハンドラーのステータスメッセージを表示する送信テストハンドラーを定義するTestWebformHandler.phpファイルがあります。イベント。

例えば:

<?php

namespace Drupal\webform_test_handler\Plugin\WebformHandler;

use Drupal\Core\Form\FormStateInterface;
use Drupal\webform\Plugin\WebformHandlerBase;
use Drupal\webform\WebformInterface;
use Drupal\webform\WebformSubmissionInterface;

/**
 * Webform submission test handler.
 *
 * @WebformHandler(
 *   id = "test",
 *   label = @Translation("Test"),
 *   category = @Translation("Testing"),
 *   description = @Translation("Tests webform submission handler behaviors."),
 *   cardinality = \Drupal\webform\Plugin\WebformHandlerInterface::CARDINALITY_SINGLE,
 *   results = \Drupal\webform\Plugin\WebformHandlerInterface::RESULTS_IGNORED,
 *   submission = \Drupal\webform\Plugin\WebformHandlerInterface::SUBMISSION_REQUIRED,
 * )
 */
class TestWebformHandler extends WebformHandlerBase {
  /**
   * {@inheritdoc}
   */
  public function preCreate(array $values) {
    $this->displayMessage(__FUNCTION__);
  }

  /**
   * {@inheritdoc}
   */
  public function postCreate(WebformSubmissionInterface $webform_submission) {
    $this->displayMessage(__FUNCTION__);
  }

  /**
   * {@inheritdoc}
   */
  public function postLoad(WebformSubmissionInterface $webform_submission) {
    $this->displayMessage(__FUNCTION__);
  }

  /**
   * {@inheritdoc}
   */
  public function preDelete(WebformSubmissionInterface $webform_submission) {
    $this->displayMessage(__FUNCTION__);
  }

  /**
   * {@inheritdoc}
   */
  public function postDelete(WebformSubmissionInterface $webform_submission) {
    $this->displayMessage(__FUNCTION__);
  }

  /**
   * {@inheritdoc}
   */
  public function preSave(WebformSubmissionInterface $webform_submission) {
    $this->displayMessage(__FUNCTION__);
  }

  /**
   * {@inheritdoc}
   */
  public function postSave(WebformSubmissionInterface $webform_submission, $update = TRUE) {
    $this->displayMessage(__FUNCTION__, $update ? 'update' : 'insert');
  }
}

次に、$webform_submissionを変更する標準的な方法を使用できます。

参照: Webフォーム送信が作成された後にアクションを実行する方法

5
kenorb

多くの試行錯誤の末、私はこれらのページの助けを借りて答えを見つけました:

https://www.drupal.org/node/2841729

https://www.drupal.org/node/2637958

アイデアは、カスタムモジュールを作成し、hook_form_alter()を使用して検証関数を追加することです。検証関数は、フォームがsetValues()メソッドを使用して永続的に保存される前に値を設定します。

ここでは、webform要素observationsを任意の値に設定しています。

function MYMODULE_form_alter(&$form,$form_state, $form_id) {
  if ($form_id == 'MYFORM') {
    $form['actions']['submit']['#validate'][] = 'MYMODULE_operation_form_validate';
    }
}

function MYMODULE_operation_form_validate(&$form, $form_state, $form_id) {
  $values = ['observations' => 777];
  $form_state->setValues($values);
}
3
Parag

Drupal 8では、 hook_ENTITY_TYPE_presave 、例:

/**
 * Implements hook_ENTITY_TYPE_presave().
 */
function mymodule_webform_submission_presave(\Drupal\webform\Entity\WebformSubmission $submission) {
  // var_dump($submission); exit;
}

ウェブフォームの要素にアクセス、検証、または変更するために$submission

参照: webform要素の作成、更新、および削除操作を追跡する方法

Drupal 7の場合: Webform送信情報を変更する方法 を参照してください。

3
kenorb

このフックを使用hook_webform_element_alter

/**
 * Implements hook_webform_element_alter().
 *
 * @param array              $element
 * @param FormStateInterface $form_state
 * @param array              $context
 */
function module_webform_element_alter(array &$element, FormStateInterface $form_state, array $context) {
    //use kint
    kint($element);
    //alter location field
    if ($element['#webform_id'] === 'my_form--location') {
        //do the logic
    }
}

ビンゴ!

2
batMask

これを行うにはいくつかの方法があります。

1.hook_webform_element_alter()

function your_module_name_webform_element_alter(array &$element, FormStateInterface $form_state, array $context) {
  if (isset($element['#webform_id'])){
    if ($element['#webform_id'] === 'abc') {
        //do the logic
    }
  }
}

よりよく理解するためにこれに従ってください https://www.drupal.org/docs/8/modules/webform/webform-cookbook/how-to-add-custom-validation-to-a-webform-element =

2.hook_form_alter()

function your_module_name_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'your_form_id') {
    $form['#validate'][] = 'your_module_name_form_validate';
  }
}

そしてあなたのロジックは検証機能に入ります

function your_module_name_form_validate($form, &$form_state) {
  $values = $form_state->getValues();
  //Your logic goes here.
}
  1. hook_ENTITY_TYPE_presave()
function your_module_name_webform_submission_presave(EntityInterface $entity) {
  // Entity new will only allow you to modify the value for first time. 
  if ($entity->isNew()) {
      $entity->setElementData('key', value);
  }
}