2

I'm working my way around Drupal API with limited success.

I want to have a URL with a form in it, so that when I "GET" that URL I get the form (have that), when I input a wrong "code" into that form and POST that same URL I get the same form with an error message (have that too), but when I POST that same URL with the right "code" I get a different code, no longer displaying the previous form.

No redirects, all the requests (posts and gets) should be targeted to domain.com/entry

This is a code I have (simplified):

function entry_menu() {
    $items['entry'] = array(
        'page callback' => 'entry_handler',
        'access arguments' => array('access entry'),
        type => MENU_CALLBACK,
    );

    return $items;
}

function entry_handler() {
    return drupal_get_form('entry_daily_code');
}

function entry_daily_code($form, &$form_state) {
    $form['code'] = array(
        '#type' => 'textfield',
        '#title' => 'Code for Today',
    );

    form['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Access',
    );

    return $form;
}

function entry_daily_code_submit($form, &$form_state) {
    if (isset($form_state['values']['code']) && $form_state['values'] == "1234") {
        drupal_set_message(t('Success'));
    }
    else {
        drupal_set_message(t('Fail'));
    }
}

I imagine that what I want to do should happen in "entry_handler".

It needs to know the status returned by the form, and to either return the form, or a different content, but I'm failing at that.

Made a diagram to illustrate my point, in case it wasn't coming across:

diagram

Thanks for any pointers in the right direction.

2

When your visitor send the form, Drupal process the input, executing the validate and submit handlers (you have only provided your submit handler).

Once handlers are executed, Drupal needs to send a page to the user (the answer), so, if no redirection is made (in $form_state['redirect']), Drupal renders the content for the current URL, so Drupal renders your form again (because is a new HTTP petition, there's no memory of past petitions).

You must do something in the submit handler to let Drupal know your visitor can see the protected content.

For example, you can set a flag in the $_SESSION data. Then, in the entry_handler check for that value: if it's there the content is rendered, if not then the form is rendered.

Something like this (I've also divided your submit handler into validate and submit handlers):

function entry_daily_code_validate($form, &$form_state) {
    if (isset($form_state['values']['code']) && $form_state['values'] != "1234") {
   form_set_error('code', 'Invalid code!');
}

function entry_daily_code_submit($form, &$form_state) {
  $_SESSION['code_validated'] = TRUE;
}


function entry_handler() {
  if ($_SESSION['code_validated' == TRUE) {
    return 'Arbitrary content';
  }
  else {
    return drupal_get_form('entry_daily_code');
  }
}

If your visitors are registered users you can edit the user account or whatever merthod you like. Remember that session data can be lost.

1
  • Thanks, that's very helpful. I thought that since I was still in the POST - RESPONSE I could access the some data from inside the handler and act accordingly. $_SESSION works, I'm counting on the login being ephemeral (I'm actually going to set $_SESSION['code_validated'] to false after delivering the content. Many thanks, again!
    – nardus
    Oct 11 '13 at 17:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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