I am developing two form input modules based on the Drupal Form API. Specifically I made a variation of the my_module module created in example 7 of the following guide: http://drupal.org/node/262422.

The forms work great, they take the input which I later write to the db, however, after doing this write to db I want the module to redirect the browser to another webpage.

I have tried to use php's header() function as follows:

header('Location: http://localhost');

As well as drupal's drupal_goto() function as follows:

drupal_goto($path = 'http://localhost', $http_response_code = 302);

and as

drupal_goto('http://localhost');

But I keep getting the following Firefox Error:

Redirect Loop
Firefox has detected that the server is redirecting the request for this address in a way that will never complete.

Can anyone suggest a way to redirect after the _submit function concludes?

Thanks!

Comments

briansea’s picture

Is the form located at http://localhost ?

guatebus’s picture

http://localhost/reply_module/form

Here's the module's code:

<?php

function reply_module_perm() {
  return array('administer reply module', 'access reply module');
}

if (user_access('access reply module' || 'administer reply module')) {

  function reply_module_menu() {
    $items = array();
    $items['reply_module/form'] = array(
      'title' => t('Reply form'),
      'page callback' => 'reply_module_form',
      'access arguments' => array('access content'),
      'description' => t('Reply form'),
      'type' => MENU_CALLBACK,
    );
    return $items;
  }

  function reply_module_form() {
    return drupal_get_form('reply_module_my_form');
  }

  function reply_module_my_form() {
    
    $host = 'localhost';
    $dbuser = 'root';
    $dbpwd = 'volcanoWorld321';

    mysql_connect($host, $dbuser, $dbpwd);
    mysql_select_db(v_test) or die (mysql_error());    
    $user2query = 'select userName from opsuser2';
    $user2result = mysql_query($user2query);
    mysql_close();
    
    unset($issueID);
    $issueID = $_POST['issueID'];

    while ($row = mysql_fetch_array($user2result)) {
      $user2array[] = $row['userName'];
    } 
 
    $form['replyby'] = array(
      '#type' => 'select',
      '#title' => t('Reply by'),
      '#options' => array($user2array),  
      '#required' => TRUE,
      '#description' => "Please select your Username",
    );

//    For testing purposes:
//    print_r($form['replyby']);

    $form['description'] = array(
      '#type' => 'textarea',
      '#title' => t('Description of Handled Issue'),
      '#description' => "Use the space above to describe how this issue was addressed. Please be specific in the sequence of steps to follow or test.",
      '#required' => TRUE,
    );

    $form['submit'] = array(
      '#type' => 'submit',
      '#value' => 'Submit',
    );
    return $form;
  }

  function reply_module_my_form_submit($form, $form_values) {

    global $user;

    //getting the submitted date
    $reply_dt = getdate();
    
    //creating the string to store in db according to mysql 'datetime' format
    $reply_date = ($reply_dt['year'] . '-' . $reply_dt['mon'] . '-' . $reply_dt['mday'] . ' ' . $reply_dt['hours'] . ':' . $reply_dt['minutes'] . ':' . $reply_dt['seconds']);
    
    //creating the ticket # 
    //$ticket = (ltrim($submt_dt['year'],'2') . $submt_dt['yday'] . '.' . $submt_dt['hours'] . '.' . $submt_dt['minutes']);

    //creating the strings to store in db from the arrays populating the 'select' inputs (combo-boxes)    
    $replyBy = $form['replyby']['#options'][0][$form_values['values']['replyby']];

    db_query("INSERT INTO replies (iid, replyBy, replyDesc, reply_date) VALUES (%d, '%s', '%s', '%s')", $_SESSION['issueID'], $replyBy, $form_values['values']['description'], $reply_date);

    drupal_set_message(t("Thank you for submitting an answer to the issue."));

  }
}
else {
  drupal_goto($path = 'http://localhost', $http_response_code = 302);
} 

It is that last else statement that would redirect in case the user is not allowed to access the page (failing the if) but Firefox produces the infinite looping error

any ideas/suggestions?

briansea’s picture

Here is why - all module files are read by the php interpeter at run time for each request. SO, since: if (user_access('access reply module' || 'administer reply module')) {

is not in a function, it gets evaluated for each request.

here is what i would do.:


function reply_module_perm() {
  return array('administer reply module', 'access reply module');
}

function reply_module_menu() 
{
	$items = array();
	$items['reply_module/form'] = array(
  'title' => t('Reply form'),
  'page callback' => 'drupal_get_form',
  'page_arguments' => array("reply_module_my_form"),
  'access arguments' => array('access reply module'),
  'description' => t('Reply form'),
  'type' => MENU_CALLBACK,
);
return $items;
}


  function reply_module_my_form() {
   
    $host = 'localhost';
    $dbuser = 'root';
    $dbpwd = 'volcanoWorld321';

    mysql_connect($host, $dbuser, $dbpwd);
    mysql_select_db(v_test) or die (mysql_error());   
    $user2query = 'select userName from opsuser2';
    $user2result = mysql_query($user2query);
    mysql_close();
   
    unset($issueID);
    $issueID = $_POST['issueID'];

    while ($row = mysql_fetch_array($user2result)) {
      $user2array[] = $row['userName'];
    }

    $form['replyby'] = array(
      '#type' => 'select',
      '#title' => t('Reply by'),
      '#options' => array($user2array), 
      '#required' => TRUE,
      '#description' => "Please select your Username",
    );

//    For testing purposes:
//    print_r($form['replyby']);

    $form['description'] = array(
      '#type' => 'textarea',
      '#title' => t('Description of Handled Issue'),
      '#description' => "Use the space above to describe how this issue was addressed. Please be specific in the sequence of steps to follow or test.",
      '#required' => TRUE,
    );

    $form['submit'] = array(
      '#type' => 'submit',
      '#value' => 'Submit',
    );
    return $form;
  }

  function reply_module_my_form_submit($form, $form_values) {

    global $user;

    //getting the submitted date
    $reply_dt = getdate();
   
    //creating the string to store in db according to mysql 'datetime' format
    $reply_date = ($reply_dt['year'] . '-' . $reply_dt['mon'] . '-' . $reply_dt['mday'] . ' ' . $reply_dt['hours'] . ':' . $reply_dt['minutes'] . ':' . $reply_dt['seconds']);
   
    //creating the ticket #
    //$ticket = (ltrim($submt_dt['year'],'2') . $submt_dt['yday'] . '.' . $submt_dt['hours'] . '.' . $submt_dt['minutes']);

    //creating the strings to store in db from the arrays populating the 'select' inputs (combo-boxes)   
    $replyBy = $form['replyby']['#options'][0][$form_values['values']['replyby']];

    db_query("INSERT INTO replies (iid, replyBy, replyDesc, reply_date) VALUES (%d, '%s', '%s', '%s')", $_SESSION['issueID'], $replyBy, $form_values['values']['description'], $reply_date);

    drupal_set_message(t("Thank you for submitting an answer to the issue."));

  }

I hope the above helped, if it needs clarification, just ask

Use the menu system to perform the access check, useing the array key 'access arguments' It will give a 403 if they cant get to it - which is better than sending then to some page and now saying why. You can also declare drupal_get_form directly from the menu as the page callback.

guatebus’s picture

Thank you Brian for your suggestion, it was pretty clear what you did. I tried it, but cannot access the module any longer, not even as admin. The browser displays the same blank screen as before, and when I navigate to a viewable location (say http://localhost) I see the following error (in the red drupal message box at the top of the page) as well as the viewable page:

warning: call_user_func_array() [function.call-user-func-array]: First argument is expected to be a valid callback, 'report_module_form' was given in /var/www/includes/menu.inc on line 348.

Are you sure your code is exact? Any other suggestions anyone? I'm sure we're moving in the right direction...

thanks to all
gtb

briansea’s picture

Have you gone back to the modules page? after maing any changes to the menu system, you have to flush the menu cache. going to the modules page will do this.

guatebus’s picture

I modified my code as suggested by Brian:

I removed the if statement from the module file and changed the 'access arguments' item on the $items['report_module/form'] array to => array('access report module') leaving it as:

function report_module_menu() {
    $items = array();
    $items['report_module/form'] = array(
      'title' => t('Report form'),
      'page callback' => 'report_module_form',
      'access arguments' => array('access report module'),
      'description' => t('Report form'),
      'type' => MENU_CALLBACK,
    );
    return $items;
  }

This solved the issue of denying access to the form. When the submit function finished, I simply used the drupal_goto() function to send the user to another page.

Thanks a bunch Brian!
gtb