1

I have the below simple if else condition for a custom module form page in buildForm method for recommendation submission. I would like my form to be displayed to all user who visit for the first time and submits and cannot submit again from the same url. If the url is used again it should just display the thank you message(if already submitted). The below code wrks perfectly if the user is logged in. Like if the user is logged in, he comes and submit, thank you message is displayed everything is saved in DB correctly. The problem comes when anonymous user comes. The page loads as expected. But after filling up the details and submit button is clicked. It reloads and the same form is displayed again(instead of the thank yo message) and then if I submit again it displays validation errors even though the fields are there and gives the thank you message. Can anyone explain me why its behaving differently for logged in and anonymous users.

    public function buildForm(array $form, FormStateInterface $form_state)
    {
       if($this->CheckRecommendationStatus())
       {
          $form = array();
          $form['form_label'] = [
          '#type' => 'processed_text',
          '#text' => t('<h3<strong>Thank you already submitted</h3>'),
          ];
        }
        else if($this->validateUrl())
        {
           $form = array();
           //it will have controls and submit button.if submit is clicked those values will be saved
        }
        return $form;
     }
     //This below method check the Database whether already the submission is made or not
     public function CheckRecommendationStatus()
     {
           $this->setUniqueIdentifier(htmlspecialchars($_GET["rec"]));
           $query = \Drupal::database()->select('m_tablename', 'mr');
           $query->fields('mr',array('id'));
           $query->condition('mr.column_name',$this->getUniqueIdentifier());
           $query->range(0,1);      
           $results = $query->execute()->fetchAll();
           return $results;
     }
1

This sounds like a caching issue. Check the cache api and make sure to set the $form['#cache'] appropriately.

When the anonymous user submits the form, it's submitted fine, but when the form loads the second time Drupal doesn't know that it should not be serving the original cached form.

You can quickly confirm that it is a caching issue by set the form to not be cached like:

$form['#cache'] = [
  'max-age' => 0,
]; 
  • It looks like a caching issue. Even though manually I am giving incorrect querystring value, still it loads correctly with previous details. I tried the above code before the if condition, it did'nt work. – user3324848 Sep 20 '18 at 22:02
  • You will need to add it below, just before the return $form; as you completely reset the form variable within each if case – sonfd Sep 20 '18 at 22:06
  • Perfect its working as expected. Thanks a lot. But why did it work for logged in users. Caching is different for them. – user3324848 Sep 20 '18 at 22:10
  • I think because caching is not enabled by default for logged in users. But I think that changed with a recent release, or is changing soon? – sonfd Sep 20 '18 at 22:15
  • 1
    the thing is that for authenticated users, all forms are currently uncacheable because they CSRF protection. However, for anonymous users, you are hitting the dynamic page cache, which by default does not consider the query argument when caching, you would need to add url.query_args.rec cache context. Note that max-age 0 is additionally not respected by the internal page cache, so you might also need to use \Drupal::service('page_cache_kill_switch')->trigger(); so it is not cached there – Berdir Sep 21 '18 at 5:57

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.