There is a bug in new D7 code - form rebuild is not happening properly on invalid submission.

Comments

iva2k’s picture

Status: Active » Fixed

After some digging I found that D7 ignores global $conf['cache'] for forms. Looks like the way CAPTCHA works relies on #process hook that gets called for cached forms. It cannot be used in BOTCHA as we need to rebuild more than one element and add JS and CSS.

I found a fix - it turns out to be very simple - set $form_state['no_cache'] = TRUE and all works again. I'm also removing $conf['cache'] = 0 bit and all notes pertaining to performance and caching.

It's not back-portable to D6 as 'no_cache' is new to D7.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

tomogden’s picture

@iva2k, what happens to a BOTCHA form when it is cached? It's a concern because of the deleterious effect the $form_state['no_cache'] boolean has on AJAX (see issue #1270986: Make BOTCHA work with AJAX).

  • Does the form not render?
  • Does the form render but lose its BOTCHA protection?
  • Does the problem affect all BOTCHA forms?
  • If there is a problem, can the user or administrator see it on the surface of the form?

Thanks for your help.

iva2k’s picture

BOTCHA uses active protection, and it makes every served form unique (even if its the "same" form). Therefore caching is not allowed. If caching would be allowed, none of the BOTCHA protected forms will ever pass validation.

adam.weingarten’s picture

Issue summary: View changes

I've been researching a conflict between botcha and feedback and I isolated the issue back to this particular patch. Feedback uses the built in AJAX api. When an ajax post happens it gets checked against the form-cache. If the form is not in the form cache an exception is thrown. Setting $form_state['no_cache'] = null seems to fix the issue in the forms/ajax situation (I'm sure it opens a whole new can of worms.). I'm guessing that some of the other AJAX issues people are seeing might be related to this as well. I'm still getting up to speed on this issue. Thinking of maybe making some conditional code to handle the ajax situation?

adam.weingarten’s picture

Status: Closed (fixed) » Active
oadaeh’s picture

Assigned: iva2k » Unassigned

Setting $form_state['no_cache'] to NULL is effectively the same as setting it to FALSE, because the checks against 'no_cache' in form.inc are only if (empty($form_state['no_cache'])), which means the form WILL be cached, so that is not a valid solution.

oadaeh’s picture