I have a form alter handler like this.

function toyotaec_form_webform_client_form_seleccionar_alter(&$form, &$form_state) {
    $concesionarias = concesionarias();

    $form['actions']['submit']['#value'] = 'Enviar';
    $form['submitted']['concesionaria']['#options'] = $concesionarias;
    $form['#validate'][] = 'toyotaec_form_webform_client_form_seleccionar_validate';
    $form['#submit'][] = 'toyotaec_form_webform_client_form_seleccionar_submit';

Actually, this code is not a hook_form_alter but a function called by the actual hook. The hook calls this function passing &$form and &$form_state also by reference.

After this, I have the corresponding handlers. Both handlers are called as expected. The handler I want to focus in is as follows:

function toyotaec_form_webform_client_form_seleccionar_submit(&$form, &$form_state) {
    $values = $form_state['values']['submitted_tree'];
    $input = &$form['submitted'];

    $concesionaria = trim($values['concesionaria']);
    $redirigir = trim($values['redirigir']);
    $modelo = trim($values['modelo']);

    //obtenemos cual es la concesionaria (por marca, descartamos las ciudades)
    $mconcesionaria = current(explode('-', $concesionaria));

    //las redirecciones diferidas van a tener una salvada incluyendo la url.
    //las redirecciones directas no van a tener salvada.
    $form_state['values']['submitted']['3'] = _redirect_bystore($mconcesionaria, $redirigir, $form_state, $concesionaria, $modelo);

For the last line, I also tried assigning $form_state['values']['submitted_tree']['url']. This url field is the 3rd field and I have to keep track of it, but even when the data is stored in the array (confirmed by using dpm() on it), the form result has a blank url field.

For this, I'm using Webforms in Drupal 7.

My question is: how can I alter the submitted data? It seems that - for the submit handler - form state is not passed by reference.

1 Answer 1


You're accepting $form_state by reference, so the changes you make will definitely persist onto the incoming variable when your function loses scope. The variable/calling function doesn't control whether it's a reference here, your function signature does. The FAPI doesn't use the old pass-by-reference style (e.g. foo(&$bar), which has been deprecated and removed), so you're in control of that.

Chances are the webform submit handlers are running before yours, so the changes you make aren't actually used by anything, despite being correctly added to the array.

To get around it, simply use a validate handler instead. This will run before the form submission, and changes you make to $form_state['values'] will be available to the webform's submit handlers (as well as your own if you need to do extra processing).

I think you can probably use exactly the same code as in your submit handler.

  • I think. My hypothesis on first place was the variable holding the state was copied, and the copy was passed to the handler (so affecting it wouldn't imply affecting the original), but the order of submit handlers... i never thought about that. Will see and reply back. Commented Apr 3, 2014 at 17:08
  • Accepting this answer since I followed the recommendation regarding the validate hook. However DRUPAL SUCKS and I'm forced to use it: if I set (as I needed to) the ['redirect'] value in the validate hook, THAT VALUE IS LOST. So the workaround involved a temporary space in the array to set the url and, in the submit handler, actually set the 'redirect' field inside the form state. Commented Apr 3, 2014 at 17:51

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.