0

How will a predefined form behave if we have two different forms that implement hook_form_alter?

I would explain my question by an example, because currently I got a crash on it:

I have a predefined user_login form in user.module

I created two new blocks called author_login and creator_login. Each of these module using the form user_login and adding new validating properties for each form by using function hook_form_alter().

The new validating properties are:

For author_login block: if user doesn't have author role, user will not be logged into system, error: "you don't have author role"

For creator_login block: if user doesn't have creator role, user will not be logged into system, error: "you don't have creator role"

But the problem is: the new login block I created works fine if only one of two modules is enable. If I enable both modules, no user cannot log in to the system through these module.

For example, I have both modules enabled, I go to author_login block and log an user named Mark, who has role Author, to the system, an error message displayed: "the user Mark doesn't have creator role". And similar to creator_login block.

Why does this happen? I thought that the hook_form_alter will alter different properties to each new module we created, make each new form works separately. But from this case I encountered, it seem like the user_login form validate all new properties that I added by using hook_form_alter. And how can I avoid this as I want these two form to work separately?

Notes: I am really sorry to post this question here because I posted the question on drupal.stackexchange but there was only one answer that couldn't help me much in finding the solution. I really need help on this question. Many thanks!

1 Answer 1

1

All implementations of the hook_form_alter() will alter the user_login forms you embed in your blocks. As you observed, your author_login form alter will not be restricted to only altering the form in your author_login block.

If you want your form alters to only alter the form in the context of their respective blocks, you have to find a way to observe the block context from them. There is no easy way to properly implement this, you will either have to add additional non-standard arguments to your form builder (the arguments passed to drupal_get_form() after the form ID), or uses some sort of global states.

A cleaner solution is to use hook_forms to define new author_login and creator_login forms that simply re-use the existing user_login form as callback but have a different form id:

/**
 * Implements hook_forms().
 */
function author_login_forms($form_id, $args) {
  $forms = array();
  $forms['author_login'] = array(
    'callback' => 'user_login',
  );
  return $forms;
}

You can then simply implement a form alter specific to your author login form.

/**
 * Implements hook_form_FORM_ID_alter().
 */
function author_login_form_author_login_alter(&$form, &$form_state) {
  $form['#validate'][] = 'author_login_validate';
}

And finally embed this form wherever you need it with

drupal_get_form('author_login');

Repeat for the creator login form.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.