Pradeep Sanjaya
Pradeep Sanjaya

Reputation: 1846

ZF2, ZF2-NoCaptcha, FormValidation

I'm using szmnmichalowski/ZF2-NoCaptcha for captcha verifications and I have following setup. How do I use Identical validator to validate 'captcha' form element with 'g-recaptcha-response' generated and embedded to form on the fly? I get 'The two given tokens do not match' error message even I type correct captcha. But I can validate it with a custom Validator.

composer.json

{
    "require": {
        "php": ">=5.3.3",
        "zendframework/zendframework": "2.3.3",
        "spoonx/sxmail": "1.4.*",
        "slm/queue": "0.4.*",
        "szmnmichalowski/zf2-nocaptcha": "dev-master"
    }
}

config/application.config.php

return array(
    'modules' => array(
        'SxMail',
        'SlmQueue',
        'Application',
        'NoCaptcha'
    )
);

module/Application/Module.php

<?php
namespace Application;

class Module implements AutoloaderProviderInterface, ConfigProviderInterface, BootstrapListenerInterface
{
    public function getFormElementConfig()
    {
        return array(
            'factories' => array(
                'Application\Form\ContactusForm' => function ($serviceManager) {
                    $form = new \Application\Form\ContactusForm();
                    return $form;
                }

            )
        );
    }
}

module/Application/src/Application/Form/ContactusForm.php

<?php
namespace Application\Form;

use Zend\Form\Element;
use Zend\Form\Form;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;


class ContactusForm extends Form implements InputFilterAwareInterface, ServiceLocatorAwareInterface
{
    protected $inputFilter;

    public function __construct($name = null)
    {
        parent::__construct('ContactUs');
    }

    public function init()
    {
        $name = new \Zend\Form\Element\Text('name');
        $name->setAttributes(array(
                'class'       => 'form-control',
                'id'          => 'name',
                'placeholder' => 'Name',
                'required'    => 'Name required'
            )
        );

        $this->add($name);

        $config = $this->getServiceLocator()->getServiceLocator()->get('config');
        $options = $config['application']['captcha'];

        $captcha = new \NoCaptcha\Captcha\ReCaptcha($options);

        $this->add(array(
            'type'  => 'Zend\Form\Element\Captcha',
            'name'  => 'captcha',
            'attributes' => array(
                'id'     => 'recaptcha-response',
            ),
            'options' => array(
                'label'   => 'Are you a bot?',
                'captcha' => $captcha
            )
        ));
    }

    public function getInputFilter()
    {
        if (!$this->inputFilter) {
            $inputFilter = new InputFilter();
            $factory = new InputFactory();

            $inputFilter->add($factory->createInput([
                'name' => 'name',
                'required' => true,
                'filters' => array(
                    array(
                        'name' => 'StripTags'
                    ),
                    array(
                        'name' => 'StringTrim'
                    )
                ),
                'validators' => array(
                    array(
                        'name' => 'not_empty',
                        "options" => array(
                            "messages" => array(
                                "isEmpty" => "Name is empty."
                            ),
                        ),
                    ),
                )
            ]));

            $inputFilter->add($factory->createInput([
                'name' => 'captcha',
                'required' => true,
                'validators' => array(
                    array(
                        'name'    => 'Identical',
                        'options' => array(
                            'token' => 'g-recaptcha-response',
                        )
                    )
                )
            ]));

            $this->inputFilter = $inputFilter;
        }

        return $this->inputFilter;
    }
}

module/Application/src/Application/Controller/IndexController.php

<?php
namespace Application\Controller;

use Application\Form\ContactusForm;

class IndexController extends ApplicationController
{
    public function __construct(
        \Application\Service\EmailService $emailService
    ) {
        $this->emailService = $emailService;
    }

    public function indexAction()
    {
        $contactUsForm = $this->getServiceLocator()->get('FormElementManager')->get('Application\Form\ContactusForm');
        $contactUsForm->setTranslator($this->translator);

        $request = $this->getRequest();

        if ($request->isPost()) {

            $postData = $request->getPost();
            $contactUsForm->setData($postData);

            if ($contactUsForm->isValid()) {
                $emailJob = $this->getJobManager()->get('Application\Job\Email');
                $emailJob->setContent(
                //content
                );
                $this->getDoctrineQueue()->push($emailJob);

                $successMessage = $this->translator->translate('Message successfully sent.');
                $this->flashMessenger()->addSuccessMessage($successMessage);
                $this->redirect()->toRoute('home');

            } else {
                $errorMessage = $this->translator->translate('Message failed. Please try again');
                $this->flashMessenger()->addErrorMessage($errorMessage);
            }
        }

        $viewModel = new ViewModel();
        $viewModel->setVariable('form', $contactUsForm);

        return $viewModel;
    }
}

Upvotes: 4

Views: 191

Answers (2)

Mike Doe
Mike Doe

Reputation: 17566

You can take a look at my free ZF2 module mxreCaptcha, which is:

  1. Much easier to use
  2. Has better unit test coverage
  3. Under CI/CD
  4. Mature and versioned
  5. Follows SemVer
  6. Used extensively in my company's commercial projects

Upvotes: 0

Saeven
Saeven

Reputation: 2300

Seems like a lot of work. Try this instead: https://github.com/Saeven/zf2-circlical-recaptcha

Disclosure: I'm the author, but at least can guarantee it works.

Upvotes: 2

Related Questions