10

Is there a way to change the order of execution of hook_form_alter in Drupal 7 without changing a module's weight or hacking Drupal Core?

I am trying to alter the element added in translation_form_node_form_alter from the translation module. When debugging the form I can't find the element so I assume my hook is being executed before the one in the translation module is.

3 Answers 3

1

I don't think so. translation_form_node_form_alter() implements hook_form_BASE_FORM_ID_alter() which I believe is called after hook_form_alter(), so even changing the module weight wouldn't be enough. I think your two options are to use a hook_form_BASE_FORM_ID_alter() and ensure you have a high enough module weight, or use hook_form_FORM_ID_alter() (if possible).

6
  • hook_form_FORM_ID_alter() IS called after hook_form_alter()
    – iStryker
    Jul 26, 2011 at 12:56
  • Solved it using hook_form_form_id_alter and module weight.
    – Bart
    Jul 26, 2011 at 13:22
  • @Bart if you used hook_form_FORM_ID_alter() then my understanding is that you shouldn't need to modify the weight at all (because all hook_form_FORM_ID_alter() calls are made after all hook_form_BASE_FORM_ID_alter()).
    – Andy
    Jul 26, 2011 at 13:31
  • @Andy, it doesn't seem to work if I use foo_form_page_node_form_alter without adjusting the weight.
    – Bart
    Jul 26, 2011 at 13:38
  • 1
    @Bart I was looking at the source to give you those details - check out the bottom of drupal_prepare_form() and drupal_alter(). I'd already noticed that the docs seemed off, so I created an issue. Dunno why it doesn't work for you without altering the system weight tho!
    – Andy
    Jul 26, 2011 at 15:21
18

Also worth mentioning, there is a new drupal 7 API called hook_module_implements_alter() which lets you alter the execution order for a given hook WIHOUT altering the module weights table.

Sample code from the API docs showing how easy this is to do:

<?php
function hook_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'rdf_mapping') {
    // Move my_module_rdf_mapping() to the end of the list. module_implements()
    // iterates through $implementations with a foreach loop which PHP iterates
    // in the order that the items were added, so to move an item to the end of
    // the array, we remove it and then add it.
    $group = $implementations['my_module'];
    unset($implementations['my_module']);
    $implementations['my_module'] = $group;
  }
}
?>
1
  • I was able to execute my hook last with this exact code. Thanks!
    – Beau
    Oct 26, 2017 at 20:16
5

Here is how to make sure your hook_form_alter is called after another modules hook_form_alter:

/**
 * Implements hook_form_alter().
 */
function my_module_form_alter(&$form, &$form_state, $form_id) {
  // do your stuff
}

/**
 * Implements hook_module_implements_alter().
 *
 * Make sure that our form alter is called AFTER the same hook provided in xxx
 */
function my_module_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'form_alter') {
    // Move my_module_rdf_mapping() to the end of the list. module_implements()
    // iterates through $implementations with a foreach loop which PHP iterates
    // in the order that the items were added, so to move an item to the end of
    // the array, we remove it and then add it.
    $group = $implementations['my_module'];
    unset($implementations['my_module']);
    $implementations['my_module'] = $group;
  }
}

This also works when the other module has provided a form_alter hook in the variation: hook_form_FORM_ID_alter. (they explain that in the documentation: hook_module_implements_alter).

I know that this post is quite similar to wiifm's post, but thought it useful with an example with hook_form_alter

1
  • Didn't work for me. Jul 11, 2017 at 11:26

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.