Oh snap! You are using an old version of browser. Update your browser to get new awesome features. Click for more details.

Magento 2 How to add native captcha to a custom form

Follow some step for using magento captcha into custom module.

Step 1. Vendor/Module/etc/config.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<customer>
<captcha>
<always_for>
<custom_form>1</custom_form>
</always_for>
</captcha>
</customer>
<captcha translate="label">
<frontend>
<areas>
<custom_form>
<label>Custom Form</label>
</custom_form>
</areas>
</frontend>
</captcha>
</default>
</config>

Step 2: Goto 'Admin -> Stores -> Configuration -> Customer -> Customer Configuration -> Captcha' and configure. You can able to see new forms value 'Custom Form'

Select form and save

Step 3: Create Vendor/Module/view/frontend/layout/yourroutid_index_index.xml

<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
<referenceContainer name="content">
<block class="Vendor\Module\Block\Customform" name="custom-index" template="custom-form.phtml">
                <container name="form.additional.info" label="Captcha">
                    <block class="Magento\Captcha\Block\Captcha" name="captcha" after="-" cacheable="false">
                        <action method="setFormId">
                            <argument name="formId" xsi:type="string">custom_form</argument>
                        </action>
                        <action method="setImgWidth">
                            <argument name="width" xsi:type="string">230</argument>
                        </action>
                        <action method="setImgHeight">
                            <argument name="width" xsi:type="string">50</argument>
                        </action>
                    </block>
                </container>
            </block>
</referenceContainer>

        <referenceBlock name="head.components">
            <block class="Magento\Framework\View\Element\Js\Components" name="captcha_page_head_components" template="Magento_Captcha::js/components.phtml"/>
        </referenceBlock>
</body>
</page>

Step 4: Vendor/Moduel/view/frontend/templates/custom-form.phtml

<div>
    <form class="custom-form"
          action="<?php echo $block->getFormAction(); ?>"
          id="custom_form"
          name="custom_form"
          method="post"
          enctype="multipart/form-data"
          data-hasrequired="<?php echo __('* Required Fields') ?>"
          data-mage-init='{"validation":{}}'>

        <h3><?php echo __('Custom Form')?></h3>
        <fieldset class="fieldset rma-info">
            <div class="field email required">
                <label class="label" for="rma_email"><?php echo __('Email')?></label>
                <input name="rma_email" id="rma_email" value="<?php echo $block->getCustomerLoggedIn() ? $data->getEmail(): "" ;?>" class="input-text" type="email" data-validate="{required:true, 'validate-email':true}" />
            </div>

            <div class="field name required">
                <label class="label" for="customer_name"><?php echo __('Name')?></label>
                <input name="customer_name" id="customer_name" value="<?php echo $block->getCustomerLoggedIn() ? $data->getFirstname(): "" ;?>" class="input-text" type="text" data-validate="{required:true}" />
            </div>

            <div class="field phone required">
                <label class="label" for="phone"><?php echo __('Phone Number') ?></label>
                <input name="phone" id="phone" class="input-text" type="text" data-validate="{required:true}" />
            </div>

            <div class="field address required">
                <label class="label" for="address"><?php echo __('Address') ?></label>
                <input name="address" id="address" class="input-text" type="text" data-validate="{required:true}" />
            </div>

            <!-- Display captcha -->
            <?php echo $block->getChildHtml('form.additional.info'); ?>
            <!-- Display captcha -->

        </fieldset>

        <div class="actions-toolbar">
            <div class="primary">
                <button type="submit" title="<?php echo __('Submit') ?>" class="action submit primary">
                    <span><?php echo __('Submit') ?></span>
                </button>
            </div>
        </div>
    </form>
</div>

Now you can able to see captcha into your form. Now need to validation your captcha using observer. So I use post controller predispatch event for validation.

Step 5: Vendor/Module/etc/frontend/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="controller_action_predispatch_yourroute_index_post">
        <observer name="captcha_custom_form" instance="Vendor\Module\Observer\CheckCustomFormObserver" />
    </event>
</config>

Step 6: Vendor/Module/Observer/CheckCustomFormObserver.php

<?php
namespace Vendor/Module\Observer;

use Magento\Framework\Event\ObserverInterface;

class CheckCaptchaFormObserver implements ObserverInterface {

    protected $_helper;

    protected $_actionFlag;

    protected $messageManager;

    protected $_session;

    protected $_urlManager;

    protected $captchaStringResolver;

    protected $redirect;

    public function __construct(
        \Magento\Captcha\Helper\Data $helper,
        \Magento\Framework\App\ActionFlag $actionFlag,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        \Magento\Framework\Session\SessionManagerInterface $session,
        \Magento\Framework\UrlInterface $urlManager,
        \Magento\Framework\App\Response\RedirectInterface $redirect,
        \Magento\Captcha\Observer\CaptchaStringResolver $captchaStringResolver
    ) {
        $this->_helper = $helper;
        $this->_actionFlag = $actionFlag;
        $this->messageManager = $messageManager;
        $this->_session = $session;
        $this->_urlManager = $urlManager;
        $this->redirect = $redirect;
        $this->captchaStringResolver = $captchaStringResolver;
    }

    public function execute(\Magento\Framework\Event\Observer $observer) {
        $formId = 'custom_form';
        $captchaModel = $this->_helper->getCaptcha($formId);

        $controller = $observer->getControllerAction();
        if (!$captchaModel->isCorrect($this->captchaStringResolver->resolve($controller->getRequest(), $formId))) {
            $this->messageManager->addError(__('Incorrect CAPTCHA'));
            $this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);
            $this->_session->setCustomerFormData($controller->getRequest()->getPostValue());
            $url = $this->_urlManager->getUrl('yourroute/index/index', ['_nosecret' => true]);
            $controller->getResponse()->setRedirect($this->redirect->error($url));
        }

        return $this;
    }
}


Reference URL

(0) comments