Issues

ZF-10991: ReCAPTCHA does work in forms using Array Notation

Issue Type: Bug Created: 2011-01-24T04:05:15.000+0000 Last Updated: 2011-07-26T09:14:34.000+0000 Status: Resolved Fix version(s): - 1.11.9 (14/Jul/11)

Reporter: Leigh Makewell (lmakewell) Assignee: Matthew Weier O'Phinney (matthew) Tags: - Zend_Form

Related issues: Attachments:

Description

If you create a form containing a ReCaptcha captcha element it will not validate if that form is using array notation.

This form will validate correctly

<pre class="highlight">
class Contact_Form_Test extends Zend_Form
{
    private static $_privKey = '';
    private static $_pubKey = '';


    public function init()
    {
        $this->setMethod('post');

        $element = new Zend_Form_Element_Captcha('recaptcha', array(
            'label' => "Please verify you're a human",
            'captcha' => 'ReCaptcha',
            'captchaOptions' => array(
                'privKey' => self::$_privKey,
                'pubKey' => self::$_pubKey,
            ),
        ));
        $this->addElement($element);
        $this->addElement('Submit', 'submit');
    }

}

This form will not validate and dies with a 'missingValue' error. Note the addition of $this->setElementsBelongTo('contact');

<pre class="highlight">
class Contact_Form_Test extends Zend_Form
{
    private static $_privKey = '';
    private static $_pubKey = '';


    public function init()
    {
        $this->setElementsBelongTo('contact');
        $this->setMethod('post');

        $element = new Zend_Form_Element_Captcha('recaptcha', array(
            'label' => "Please verify you're a human",
            'captcha' => 'ReCaptcha',
            'captchaOptions' => array(
                'privKey' => self::$_privKey,
                'pubKey' => self::$_pubKey,
            ),
        ));
        $this->addElement($element);
        $this->addElement('Submit', 'submit');
    }

}

Comments

Posted by Kai Uwe (kaiuwe) on 2011-01-24T04:46:39.000+0000

Please use always the code tags!

Posted by Guy Halford-Thompson (guyht) on 2011-01-24T05:34:55.000+0000

Edit: Added code tags

Posted by Matthew Weier O'Phinney (matthew) on 2011-07-11T21:15:35.000+0000

On analysis, this appears to be due to a change in the ReCaptcha JavaScript API. Previously, it would use the element name in order to find and populate the challenge and response values, but now appears to be hard-coded to use only the keys "recaptcha_challenge_field" and "recaptcha_response_field" -- which makes it (a) impossible to namespace these in a form, and (b) have more than one ReCaptcha on a single page (since whichever ReCaptcha operates last populates those keys in the POST).

What's more frustrating is that if you disable JS, it's actually possible to use namespaced values via the

section, as it uses the existing elements you create via Zend_Form. As such, I'm unsure how to resolve this issue. We could potentially generate some JS that wraps the ReCaptcha API, but this could prove to be a moving target and maintenance nightmare. Another option is to support namespaces via

only, and document a methodology for pre-seeding the values yourself:

$formValues         = $this->_request->getPost('contact', array());
if (!isset($formValues['recaptcha_challenge_field'])) {
$formValues['recaptcha_challenge_field'] = $this->_request->getPost('recaptcha_challenge_field', '');
}
if (!isset($formValues['recaptcha_response_field'])) {
$formValues['recaptcha_response_field'] = $this->_request->getPost('recaptcha_response_field', '');
}
if (!$form->isValid($formValues)) { ... }

Finally, we could raise an exception if we determine that the element is part of a form array.

Guy, Leigh, which approach would you like to see?

Posted by Matthew Weier O'Phinney (matthew) on 2011-07-11T21:35:12.000+0000

I've discovered other folks have had similar issues: http://ish.io/embedded/formish/recaptcha.html

I think we may be able to munge this during onSubmit by doing a query on the given form for the appropriate elements, and then creating some new hidden ones that are namespaced but with the same values. I'll try and get something in for this in the next day or two. (We hit this on the ZF site, btw. :) )

Posted by Matthew Weier O'Phinney (matthew) on 2011-07-12T16:01:06.000+0000

The following dojo code worked for me to make the JS version of ReCaptcha work:

<pre class="highlight">
dojo.create("input", {type: "hidden", id: "contact-captcha-challenge", name: "contact[recaptcha_challenge_field]"}, dojo.byId("captcha-element"));
dojo.create("input", {type: "hidden", id: "contact-captcha-response", name: "contact[recaptcha_response_field]"}, dojo.byId("captcha-element"));
dojo.connect(dojo.byId("contact"), "onsubmit", function(e) { dojo.attr("contact-captcha-response", {value: dojo.attr("recaptcha_response_field", "value")}); dojo.attr("contact-captcha-challenge", {value: dojo.attr("recaptcha_challenge_field", "value")});});

Basically, it adds two hidden fields named appropriately into the DOM where the captcha element should live, and then binds to the form's onSubmit event in order to copy the recaptcha information into those hidden fields.

This can probably be written as a custom decorator using generic JS (using document.getElementById() and element.value).

Posted by Matthew Weier O'Phinney (matthew) on 2011-07-12T17:59:38.000+0000

Fixed in current trunk and 1.11 release branch via a custom decorator for the ReCaptcha captcha element.

Posted by Thanos Kyritsis (djart) on 2011-07-18T14:01:34.000+0000

Subversion revision #24223 for library/Zend/Form/Element/Captcha.php may have fixed ReCaptcha, but broke at least two other Captchas (I tried Figlet and Image).

The example at http://framework.zend.com/manual/en/… no longer works, because the developer now (since 1.11.9) needs to explicitly add the 'captcha' decorator to the figlet (or image captcha) form element.

Should I open a new issue for this ?

Posted by Matthew Weier O'Phinney (matthew) on 2011-07-18T14:14:06.000+0000

Please do.

I recall seeing the logic for adding the captcha decorator, as I had to add some conditional logic not to load it if one was already loaded (as, for example, with the Word or ReCaptcha decorators); it may be that this conditional logic may have introduced a new break. I had to add tests to ensure that the ReCaptcha decorator was being invoked; my guess is that we're missing tests for the others.

Posted by Kai Uwe (kaiuwe) on 2011-07-26T09:14:34.000+0000

ZF-11609 - ZF 1.11.9: No Captcha img rendered

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts