web-dev-qa-db-ja.com

drupalでフォーム送信を解釈する方法

1つのページを作成するカスタムモジュールを作成しました。そのページで、新しいコンテンツを作成するための既存のフォームをロードし、パスワードフィールドを追加します。ロードしたフォームには、メールフィールドがあります。フォームを送信する前に、電子メールフィールドにあるユーザー名と、パスワードフィールドで提供されるパスワードを持つユーザーが存在するかどうかを確認します。ここに私は3つのシナリオがあります:

  1. ユーザーが存在しない場合は、メールとパスワードを取得してアカウントを作成し、コンテンツを作成します
  2. ユーザーが存在し、パスワードが正しい場合は、コンテンツを作成します
  3. ユーザーは存在するがパスワードが正しくない場合、フォームの送信を停止します

私の問題は、フォームの送信を停止する方法がわからないことです(シナリオ番号3を参照しています)。どんな提案も最も認められている

次に、ページ関数のコールバックを示します。

function add_new_article_simple_page() {
  module_load_include('inc', 'node', 'node.pages');
  $node_form = new stdClass;
  $node_form->type = 'announcement';
  $node_form->language = LANGUAGE_NONE;
  $form = drupal_get_form('announcement_node_form', $node_form);
  return $form;
}

パスワードフィールドを挿入する変更関数:

function add_new_article_form_alter(&$form, &$form_state, $form_id){
  if($form_id=='announcement_node_form')
  {
    $form['#after_build'][] = 'add_new_article_after_build';
    $form['account_password'] = array(
        '#title' => 'Parola',
        '#type' => 'password',
        '#required' => TRUE,
    );
    $form['#submit'][] = 'add_new_article_form_submit';

    return $form;
  }
}

フォーム送信機能

function add_new_article_form_submit($form, &$form_state){
  $email=$form_state['values']['field_email']['und'][0]['value'];
  $password=$form_state['values']['account_password'];
  //check if the email even exists
  if(!db_query("SELECT COUNT(*) FROM {users} WHERE name = '".$email."';")->fetchField())
  //create the new account
  {     
    $edit = array(
        'name' => $email,
        'pass' => $password,
        'mail' => $email,
        'init' => $email,
        'roles' => array('4' => 'standard user'),
        'status' => 0,
        'access' => REQUEST_TIME,
    );
    $loc_var=user_save(drupal_anonymous_user(), $edit);
    $GLOBALS['new_user']=$loc_var->uid;     
  }
  else
  {
    //check if username + password are valid combination
    if($uid = user_authenticate($email,$password))
        //log in user after account creation
    else
        //this is where I want to interrupt the submission of the form
        form_set_error('account_password', 'Parola nu este buna pentru acest email.');
  }
}

3番目のシナリオをテストすると、コンテンツが作成され、ページがそのコンテンツページにジャンプし、そこにエラーメッセージが表示されます

私はhook_form_alterを試すという提案に従ってきたので、常にエラーを返すはずの簡単な検証関数を書きました。問題は、コンテンツがまだ送信および保存されていることです。これはhook_form_validateも呼び出さないようです。ここに関数があります:

function add_new_article_form_validate($form, &$form_state) 
{
    $email=$form_state['values']['field_email']['und'][0]['value'];
    $password=$form_state['values']['account_password'];
    form_set_error('account_password',t('The form is being validated.'.$email.' and '.$password));
}

ありがとう、クリスティ

1
Cristi

Submit関数を追加したら、validate関数を追加してみてください。

function add_new_article_form_alter(&$form, &$form_state, $form_id){
  if($form_id=='announcement_node_form')
  {
    $form['#after_build'][] = 'add_new_article_after_build';
    $form['account_password'] = array(
        '#title' => 'Parola',
        '#type' => 'password',
        '#required' => TRUE,
    );

    $form["#validate"][] = 'add_new_article_form_validate';
    $form['#submit'][] = 'add_new_article_form_submit';

    return $form;
  }
}
3
Scott Joudry

クリスティ、

HOOK_form_alterを使用してカスタムフォーム_add_new_article_simple_page_を変更した理由が正しくわかりません。ただし、フォームAPIを使用する簡単なプロセスは次のとおりです。

  1. my_custom_form()としてフォームを作成します。
  2. 検証関数をmy_custom_form_validate($form, &$form_state)として作成します。
  3. 送信関数my_custom_form_submit($form, &$form_state)を作成します。

検証関数では、3番目の条件のみをチェックしてからform_set_error('field_name', t("Password doesn't match"));を設定する必要があります

送信機能では、#1または#2の他のビジネスロジックを適用して、コンテンツまたはユーザーを作成します。

0

Hook_validateを使用するか、実際に[送信]をクリックする前に一部のデータを検証する場合は、Drupal form apiの#ajax。

/**    
 * Implementation of hook_form().
 */
function poll_form(&$node, $form_state) {
  $form['choice_wrapper']['poll_more'] = array(
    '#type' => 'submit',
    '#value' => t('More choices'),
    '#description' => t("If the amount of boxes above isn't enough, click here to add more choices."),
    '#weight' => 1,
    '#submit' => array('poll_more_choices_submit'), // If no javascript action.
    '#ajax' => array(
      'callback' => 'poll_choice_js',
      'wrapper' => 'poll-choices',
      'method' => 'replace',
      'effect' => 'fade',
    ),
  );
}    

/**
 * Menu callback for AJAX additions. Render the new poll choices.
 */
function poll_choice_js($form, $form_state) {
  return $form['choice_wrapper']['choice'];
} 

これは#ajaxのドキュメントです

0
CR47