Magento 2 - Cách thêm captcha vào biểu mẫu tùy chỉnh


28

Tôi đang phát triển một mô-đun tùy chỉnh có chứa một biểu mẫu. Tôi muốn thêm một hình ảnh xác thực vào nó. Và chúng tôi muốn sử dụng thư viện captcha mặc định Magento để captcha phù hợp với thư mục trong mẫu đăng ký.

Câu trả lời:


35

Bạn cần làm theo một số bước để sử dụng captcha magento vào mô-đun tùy chỉnh.

Bước 1 : Vendor/Module/etc/config.xml

<? xml phiên bản = "1.0"?>
<config xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: noNamespaceSchemaLocation = "urn: magento: module: Magento_Store: etc / config.xsd">
    <mặc định>
        <khách hàng>
            <captcha>
                <show_to_logged_in_user>
                    <custom_form> 1 </ custom_form>
                </ show_to_logged_in_user>
                <always_for>
                    <custom_form> 1 </ custom_form>
                </ always_for>
            </ captcha>
        </ khách hàng>
        <captcha dịch = "nhãn">
            <lối vào>
                <khu vực>
                    <custom_form>
                        <nhãn> Biểu mẫu tùy chỉnh </ nhãn>
                    </ custom_form>
                </ khu vực>
            </ lối vào>
        </ captcha>
    </ mặc định>
</ config>

Bước 2: Goto ' Admin -> Cửa hàng -> Cấu hình -> Khách hàng -> Cấu hình khách hàng -> Captcha ' và định cấu hình. Bạn có thể thấy giá trị biểu mẫu mới 'Biểu mẫu tùy chỉnh'

Bước 3: Tạo Vendor/Module/view/frontend/layout/yourroutid_index_index.xml

<? xml phiên bản = "1.0"?>
<page xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" layout = "1column" xsi: noNamespaceSchemaLocation = "urn: magento: framework: Xem / Bố cục / etc / page_configuration.xsd">
    <đầu>
        <title> Biểu mẫu tùy chỉnh </ title>
    </ đầu>
    <cơ thể>
        <ReferenceContainer name = "content">
            <block class = "Vendor \ Module \ Block \ CaptchaForm" name = "contactForm" template = "Vendor_Module :: captchaform.phtml">
                <tên container = "form.additable.info" nhãn = "Mẫu thông tin bổ sung">
                    <block class = "Magento \ Captcha \ Block \ Captcha" name = "captcha" after = "-" cacheable = "false">
                        <hành động phương thức = "setFormId">
                            <tên đối số = "formId" xsi: type = "chuỗi"> custom_form </ argument>
                        </ hành động>
                        <hành động phương thức = "setImgWidth">
                            <tên đối số = "chiều rộng" xsi: type = "chuỗi"> 230 </ argument>
                        </ hành động>
                        <hành động phương thức = "setImgHeight">
                            <tên đối số = "chiều rộng" xsi: type = "chuỗi"> 50 </ argument>
                        </ hành động>
                    </ chặn>
                </ container>
            </ chặn>
        </ ReferenceContainer>
        <ReferenceBlock name = "head.components">
            <block class = "Magento \ Framework \ View \ Element \ Js \ Linh kiện" name = "captcha_page_head_components" template = "Magento_Captcha :: js / thành phần.phtml" />
        </ ReferenceBlock>
    </ cơ thể>
</ trang>

Bước 4: Vendor/Module/Block/CaptchaForm.php

không gian tên Nhà cung cấp \ Module \ Block;


lớp CaptchaForm mở rộng \ Magento \ Framework \ View \ Element \ Template
{
    Hàm công khai getFormAction ()
    {
        trả về $ this-> getUrl ('yourroute / index / post', ['_secure' => true]);
    }
}

Bước 5: Vendor/Moduel/view/frontend/templates/captchaform.phtml

<form class = "liên hệ mẫu"
      hành động = "<? php / * @escapeNot Đã nhận * * echo $ block-> getFormAction ();?>"
      id = "mẫu liên hệ"
      phương thức = "bài"
      data-hasrequired = "<? php / * @escapeNot Tweet * / echo __ ('* Trường bắt buộc')?>"
      data-mage-init = '{"xác thực": {}}'>
    <fieldset class = "fieldset">
        <Legend class = "Legend"> <span> <? php / * @escapeNot đã nhận xét * / echo __ ('Viết cho chúng tôi')?> </ span> </ Legend> <br />

        <div class = "tên trường bắt buộc">
            <nhãn lớp = "nhãn" cho = "tên"> <span> <? php / * @escapeNot Tweet * / echo __ ('Tên')?> </ span> </ nhãn>
            <div class = "control">
                <input name = "name" id = "name" title = "<? php / * @escapeNot Tweet * / echo __ ('Name')?>" value = "" class = "input-text" type = "text" data-verifyate = "{required: true}" />
            </ div>
        </ div>
        <div class = "email trường bắt buộc">
            <nhãn lớp = "nhãn" cho = "email"> <span> <? php / * @escapeNot Tweet * / echo __ ('Email')?> </ span> </ nhãn>
            <div class = "control">
                <input name = "email" id = "email" title = "<? php / * @escapeNot Tweet * / echo __ ('Email')?>" value = "" class = "input-text" type = "email" data-validate = "{required: true, 'verifyate-email': true}" />
            </ div>
        </ div>
        <? php echo $ block-> getChildHtml ('form.additable.info'); ?>
    </ fieldset>
    <div class = "hành động-thanh công cụ">
        <div class = "chính">
            <input type = "hidden" name = "hideit" id = "hideit" value = "" />
            <button type = "submit" title = "<? php / * @escapeNot Tweet * / echo __ ('Gửi')?>" class = "hành động gửi chính">
                <span> <? php / * @escapeNot Tweet * / echo __ ('Gửi')?> </ span>
            </ nút>
        </ div>
    </ div>
</ mẫu>

Bây giờ bạn có thể thấy captcha vào biểu mẫu của bạn. Bây giờ cần xác thực captcha của bạn bằng cách sử dụng observer. Vì vậy, tôi sử dụng sự kiện preispatch điều khiển bài để xác nhận.

Bước 6: Vendor/Module/etc/frontend/events.xml

<? xml phiên bản = "1.0"?>
<config xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: noNamespaceSchemaLocation = "urn: magento: framework: Event / etc / event.xsd">
    <tên sự kiện = "control_action_predispatch_yourroute_index_post">
        <observer name = "captcha_custom_form" instance = "Nhà cung cấp \ Module \ Observer \ CheckCustomFormObserver" />
    </ sự kiện>
</ config>

Bước 7: Vendor/Module/Observer/CheckCustomFormObserver.php

không gian tên Nhà cung cấp \ Module \ Observer;

sử dụng Magento \ Framework \ Event \ ObserverInterface;
sử dụng Magento \ Framework \ App \ Request \ DataPersistorInterface;
sử dụng Magento \ Framework \ App \ ObjectManager;
sử dụng Magento \ Captcha \ Observer \ CaptchaStringResolver;

lớp CheckCustomFormObserver thực hiện ObserverInterface
{
    / **
     * @var \ Magento \ Captcha \ Người trợ giúp \ Dữ liệu
     * /
    được bảo vệ $ _rcper;

    / **
     * @var \ Magento \ Framework \ Ứng dụng \ ActionFlag
     * /
    được bảo vệ $ _actionFlag;

    / **
     * @var \ Magento \ Framework \ Message \ ManagerInterface
     * /
    được bảo vệ $ messageManager;

    / **
     * @var \ Magento \ Framework \ App \ Feedback \ RedirectInterface
     * /
    bảo vệ $ redirect;

    / **
     * @var CaptchaStringResolver
     * /
    được bảo vệ $ captchaStringResolver;

    / **
     * @var DataPersistorInterface
     * /
    tư nhân $ dataPersistor;

    / **
     * @param \ Magento \ Captcha \ Helper \ Data $ người trợ giúp
     * @param \ Magento \ Framework \ App \ ActionFlag $ actionFlag
     * @param \ Magento \ Framework \ Message \ ManagerInterface $ messageManager
     * @param \ Magento \ Framework \ App \ Feedback \ RedirectInterface $ redirect
     * @param CaptchaStringResolver $ captchaStringResolver
     * /
    chức năng công cộng __construct (
        \ Magento \ Captcha \ Helper \ Data $ helper,
        \ Magento \ Framework \ App \ ActionFlag $ actionFlag,
        \ Magento \ Framework \ Message \ ManagerInterface $ messageManager,
        \ Magento \ Framework \ App \ Feedback \ RedirectInterface $ redirect,
        CaptchaStringResolver $ captchaStringResolver
    ) {
        $ this -> _ helper = $ helper;
        $ this -> _ actionFlag = $ actionFlag;
        $ this-> messageManager = $ messageManager;
        $ this-> redirect = $ redirect;
        $ this-> captchaStringResolver = $ captchaStringResolver;
    }

    / **
     * Kiểm tra CAPTCHA trên biểu mẫu tùy chỉnh
     *
     * @param \ Magento \ Framework \ Event \ Observer $ người quan sát
     * @return khoảng trống
     * /
    thực thi chức năng công cộng (\ Magento \ Framework \ Event \ Observer $ observer)
    {
        $ formId = 'custom_form';
        $ captcha = $ this -> _ helper-> getCaptcha ($ formId);
        if ($ captcha-> isRequired ()) {
            / ** @var \ Magento \ Framework \ App \ Action \ Action $ bộ điều khiển * /
            $ control = $ observer-> getControllAction ();
            if (! $ captcha-> isC chính xác ($ this-> captchaStringResolver-> giải quyết ($ control-> getRequest (), $ formId))) {
                $ this-> messageManager-> addError (__ ('CAPTCHA không chính xác.'));
                $ this-> getDataPersistor () -> set ($ formId, $ control-> getRequest () -> getPostValue ());
                $ this -> _ actionFlag-> set ('', \ Magento \ Framework \ App \ Action \ Action :: FLAG_NO_DISPATCH, true);
                $ this-> redirect-> redirect ($ control-> getResponse (), 'yourroute / index / index');
            }
        }
    }

    / **
     * Nhận dữ liệu liên tục
     *
     * @return DataPersistorInterface
     * /
    Hàm riêng getDataPersistor ()
    {
        if ($ this-> dataPersistor === null) {
            $ this-> dataPersistor = ObjectManager :: getInstance ()
                -> get (DataPersistorInterface :: class);
        }

        trả về $ this-> dataPersistor;
    }
}

Rất chi tiết. Tôi sẽ thử nó.
Paul

@Sohel Rana làm thế nào có thể thêm nó vào mẫu đánh giá sản phẩm
supriya mishra

@supriyamishra cần kiểm tra
Sohel Rana

1
Xin chào captcha được hiển thị nhưng bộ điều khiển quan
sát_action_predispatch

1
Tôi đã giải quyết lỗi trên nhưng tôi không thể thấy hình ảnh xác thực trong biểu mẫu tùy chỉnh của mình
jafar pinjar

1

Đối với những người không thể làm việc này, bạn có thể cần phải làm những gì tôi đã làm:

Lý do bạn captcha có thể không hiển thị là vì cài đặt cơ sở là sử dụng khối captcha mặc định mà trong _toHtml sẽ kiểm tra xem có bắt buộc captcha không.

Nếu bạn có cài đặt captcha để luôn hiển thị hơn bạn có thể không gặp phải vấn đề này, tuy nhiên nếu nó không được đặt thành luôn hiển thị captcha và bạn không muốn luôn hiển thị captcha (tức là tạo / đăng nhập tài khoản, v.v.) đặt logic cho chỉ captcha tùy chỉnh của bạn thành "Luôn luôn được yêu cầu".

trên dòng 69 của nhà cung cấp / magento / module-captcha / Block / Captcha / DefaultCaptcha.php bạn sẽ thấy:

    /**
 * Renders captcha HTML (if required)
 *
 * @return string
 */
protected function _toHtml()
{

    if ($this->getCaptchaModel()->isRequired()) {
        $this->getCaptchaModel()->generate();
        return parent::_toHtml();
    }
    return '';
}

$this->getCaptchaModel()các cuộc gọi $this->_captchaData->getCaptcha()trong nhà cung cấp / magento / module-captcha / Helper / Data.php

    /**
 * Get Captcha
 *
 * @param string $formId
 * @return \Magento\Captcha\Model\CaptchaInterface
 */
public function getCaptcha($formId)
{
    if (!array_key_exists($formId, $this->_captcha)) {
        $captchaType = ucfirst($this->getConfig('type'));
        if (!$captchaType) {
            $captchaType = self::DEFAULT_CAPTCHA_TYPE;
        } elseif ($captchaType == 'Default') {
            $captchaType = $captchaType . 'Model';
        }

        $this->_captcha[$formId] = $this->_factory->create($captchaType, $formId);
    }
    return $this->_captcha[$formId];
}

Ở đây phương thức getCaptcha kiểm tra giá trị cấu hình cho loại captcha để kết xuất và tải nhà máy của nó với $this->_factory->create()

Tuy nhiên bước vào lớp học nhà máy này, bạn sẽ thấy

 public function create($captchaType, $formId)
{
    $className = 'Magento\Captcha\Model\\' . ucfirst($captchaType);

    $instance = $this->_objectManager->create($className, ['formId' => $formId]);
    if (!$instance instanceof \Magento\Captcha\Model\CaptchaInterface) {
        throw new \InvalidArgumentException(
            $className . ' does not implement \Magento\Captcha\Model\CaptchaInterface'
        );
    }
    return $instance;
}

Vấn đề ở đây là không có vấn đề gì nhà máy sẽ tìm kiếm trong mô-đun Magento Captcha cho bất kỳ mô hình Nhà máy nào .. vì vậy

Chúng ta cần tạo một plugin để quấn quanh trình trợ giúp và kiểm tra khóa biểu mẫu của chúng ta và nếu đó là khóa biểu mẫu của chúng ta đang sử dụng, chúng ta cần tạo một lớp nhà máy mới tải mô hình của chúng ta mở rộng \ Magento \ Captcha \ Model \ DefaultModel và chồng chéo phương thức isRequired (). Một cái gì đó trông như thế này:

trong \ Your \ Module \ etc \ di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

<!--Custom Captcha-->
<type name="\Magento\Captcha\Helper\Data">
    <plugin name="custom-captcha" type="Your\Module\Plugin\Helper\CaptchaData" />
</type>

trong \ Module \ Plugin \ Helper \ CaptchaData của bạn

<?php

namespace Your\Module\Plugin\Helper;

class CaptchaData
{
protected $_captcha = [];

public function __construct(
    \Your\Module\Model\CaptchaFactory $captchaFactory
) {
    $this->captchaFactory = $captchaFactory;
}

/**
 * @param \Magento\Captcha\Helper\Data $subject
 * @param \Closure $proceed
 * @param $formId
 * @return mixed
 */
public function aroundGetCaptcha(\Magento\Captcha\Helper\Data $subject, \Closure $proceed, $formId)
{
    if ($formId == 'your_form_key') {
        $this->_captcha[$formId] = $this->captchaFactory->create();
        return $this->_captcha[$formId];

    }
    return $proceed($formId);

}

}

trong \ Your \ Module \ Model \ CaptchaFactory

<?php
/**
* Captcha model factory
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Your\Module\Model;

class CaptchaFactory
{
/**
 * @var \Magento\Framework\ObjectManagerInterface
 */
protected $_objectManager;

/**
 * @param \Magento\Framework\ObjectManagerInterface $objectManager
 */
public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager)
{
    $this->_objectManager = $objectManager;
}

/**
 * Get captcha instance
 *
 * @param string $captchaType
 * @param string $formId
 * @return \Magento\Captcha\Model\CaptchaInterface
 * @throws \InvalidArgumentException
 */
public function create()
{
    $instance = $this->_objectManager->create('Your\Module\Model\Captcha', ['formId' => 'event_subscriber']);
    if (!$instance instanceof \Magento\Captcha\Model\CaptchaInterface) {
        throw new \InvalidArgumentException(
            'Your\Module\Model\Captcha does not implement \Magento\Captcha\Model\CaptchaInterface'
        );
    }
    return $instance;
}
}

và cuối cùng, mô hình của bạn để vượt qua tham số được yêu cầu trong \ Your \ Module \ Model \ Captcha :

<?php

namespace Your\Module\Model;

class Captcha extends \Magento\Captcha\Model\DefaultModel
{
    public function isRequired($login = null)
    {
        return true;
    }
 }

0

Tôi cần captcha trong trang thuê bao bản tin cảm ơn vì vậy tôi đã sử dụng công cụ quan sát bản tin và captcha làm việc trong trang bản tin cho tôi.

1) ứng dụng / mã / Vendorname / Modulename / 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>
                <shown_to_logged_in_user>
                    <custom_newsletter>1</custom_newsletter>
                </shown_to_logged_in_user>
                <always_for>
                    <custom_newsletter>1</custom_newsletter>
                </always_for>
            </captcha>
        </customer>
        <captcha translate="label">
            <frontend>
                <areas>
                    <custom_newsletter>
                        <label>Newsletter Form</label>
                    </custom_newsletter>
                </areas>
            </frontend>
        </captcha>
    </default>
</config>

2) Goto 'Admin -> Cửa hàng -> Cấu hình -> Khách hàng -> Cấu hình khách hàng -> Captcha' và định cấu hình. Bạn có thể thấy giá trị biểu mẫu mới 'Mẫu bản tin'.

3) sao chép tệp bố cục trong chủ đề (default.xml)

<block class="Magento\Newsletter\Block\Subscribe" name="subscribe form " template="Magento_Newsletter::subscribe.phtml">
                <container name="form.additional.info" label="Form Additional Info">
                    <block class="Magento\Captcha\Block\Captcha" name="captcha" after="-" cacheable="false">
                        <action method="setFormId">
                            <argument name="formId" xsi:type="string">custom_newsletter</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>

4) Tạo trình quan sát -> tạo tệp event.xml trong ứng dụng / mã / Vendorname / Modulename / etc / frontend

 <?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_newsletter_subscriber_new">
        <observer name="captcha_newletter_form" instance="Vendorname/Modulename/Observer\CheckCustomFormObserver" />
    </event>
</config>

5) Tạo mô hình người quan sát và kiểm tra ứng dụng captcha / mã / Vendorname / Modulename / Observer / CheckCustomFormObserver.php

public function execute(\Magento\Framework\Event\Observer $observer)
        {   $formId = 'custom_newsletter';
            $captcha = $this->_helper->getCaptcha($formId);
            if ($captcha->isRequired()) {
                /** @var \Magento\Framework\App\Action\Action $controller */
                $controller = $observer->getControllerAction();
                $params=$controller->getRequest()->getPost();
                $currentpage = $params['currentpage'];


                if (!$captcha->isCorrect($this->captchaStringResolver->resolve($controller->getRequest(), $formId))) {                
                    $this->messageManager->addError(__('Incorrect CAPTCHA.'));
                    $this->getDataPersistor()->set($formId, $controller->getRequest()->getPostValue());
                    $this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);
                    $this->redirect->redirect($controller->getResponse(), $currentpage);
                }
            }
        }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.