The custom theme HTML is only generated and included once per page request if AJAX API is turned off. We're using a complex setup that causes nodes to potentially be rendered twice (though only included in the page HTML once), which is preventing reCAPTCHA from working. There may be other legitimate reasons that the reCAPTCHA is rendered more than once, requiring this patch (or something like it).

Relevant blocks of code in recaptcha.module:

static $_recaptcha_jsadded = FALSE;
if ($_recaptcha_jsadded == FALSE && $recaptcha_ajax_api == FALSE) {
  $_recaptcha_jsadded = TRUE;

  // Add support to display the custom theme.
  if ($recaptcha_theme == 'custom') {
    $recaptcha_options['custom_theme_widget'] = 'recaptcha_custom_theme_widget';
    $recaptcha_form_value = theme('recaptcha_custom_widget');
  }
if ($recaptcha_ajax_api == FALSE) {
  $captcha['form']['captcha_form'] = array(
    '#type' => 'item',
    '#markup' => ($recaptcha_form_value ? '<div id="recaptcha_custom_theme_widget">' . $recaptcha_form_value . '</div>' : '') . $html,
  );
}
else {
  $html = ($recaptcha_theme == 'custom') ? theme('recaptcha_custom_widget') : '';

Because of the static $_recaptcha_jsadded variable, $recaptcha_form_value is only built once, and that variable controls the HTML being output only when AJAX API is not used.

Arguably, $recaptcha_form_value should be removed, since it is being set for all requests but is only used as a toggle in the non-AJAX API version, and for AJAX API requests theme('recaptcha_custom_widget') is invoked directly.

Attached is a patch that moves the HTML generation out of the $_recaptcha_jsadded-controlled IF block, increases code reuse (theme('recaptcha_custom_widget') is only called once in the function body) and also cleans up another flag variable, $html, which is only used for AJAX API renders anyway.

Note: the attached patch does not attempt to solve the issue of multiple custom-themed reCAPTCHAs on a single page; that remains a problem because of duplicate "recaptcha_custom_theme_widget" HTML IDs. This patch merely fixes rendering the HTML every time the render function is called, which it already is for AJAX API renders (the AJAX API version also suffers from duplicate "recaptcha_ajax_api_container" HTML IDs).

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Liam Morland’s picture

Multiple reCAPTCHAs on a single page is dealt with in #1833822: Allow multiple instances of reCAPTCHA on the same page.

Liam Morland’s picture

Status: Active » Fixed

Status: Fixed » Closed (fixed)

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