Magento 2 - Özel bir forma captcha ekleme


28

Form gönderimi içeren özel bir modül geliştiriyorum. Ona bir captcha eklemek istiyorum. Ve Magento varsayılan captcha kütüphanesini kullanmak istiyoruz, böylece captcha kayıt formundaki ile tutarlı olacak.

Yanıtlar:


35

Özel modülde magento captcha'yı kullanmak için bir adım atmanız gerekir.

Aşama 1 : Vendor/Module/etc/config.xml

<? xml version = "1.0"?>
<config xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: noNamespaceSchemaLocation = "urn: magento: modül: Magento_Store: etc / config.xsd">
    <Varsayılan>
        <Müşteri>
            <Kaptan>
                <Shown_to_logged_in_user>
                    <Custom_form> 1 </ custom_form>
                </ Shown_to_logged_in_user>
                <Always_for>
                    <Custom_form> 1 </ custom_form>
                </ Always_for>
            </ Kaptan>
        </ Müşteri>
        <captcha translate = "label">
            <Önyüzü>
                <Alanları>
                    <Custom_form>
                        <label> Özel Form </label>
                    </ Custom_form>
                </ Alanları>
            </ Kullanıcı arayüzü>
        </ Kaptan>
    </ Varsayılan>
</ Config>

Adım 2: ' Yönetici -> Mağazalar -> Yapılandırma -> Müşteri -> Müşteri Yapılandırması -> Captcha ' seçeneğine gidin ve yapılandırın. 'Özel Form' değerinde yeni formlar görebilirsiniz

Adım 3: Yarat Vendor/Module/view/frontend/layout/yourroutid_index_index.xml

<? xml version = "1.0"?>
<sayfa xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" layout = "1column" xsi: noNamespaceSchemaLocation = "urn: magento: framework: Görüntüle / Layout / etc / page_configuration.xsd">
    <Head>
        <title> Özel Form </title>
    </ Head>
    <Body>
        <referenceContainer name = "content">
            <block class = "Satıcı \ Modül \ Blok \ CaptchaForm" name = "contactForm" şablon = "Satıcı_Modül :: captchaform.phtml">
                <container name = "form.additional.info" label = "Ek Bilgi Formu">
                    <block class = "Magento \ Captcha \ Block \ Captcha" name = "captcha" sonra = "-" cacheable = "false">
                        <action method = "setFormId">
                            <argument name = "formId" xsi: type = "string"> custom_form </argument>
                        </ Eylem>
                        <action method = "setImgWidth">
                            <argument name = "width" xsi: type = "string"> 230 </argument>
                        </ Eylem>
                        <action method = "setImgHeight">
                            <argument name = "width" xsi: type = "string"> 50 </argument>
                        </ Eylem>
                    </ Blok>
                </ Kap>
            </ Blok>
        </ ReferenceContainer>
        <referenceBlock name = "head.components">
            <block class = "Magento \ Framework \ Görünüm \ Eleman \ Js \ Components" name = "captcha_page_head_components" template = "Magento_Captcha :: js / components.phtml" />
        </ ReferenceBlock>
    </ Body>
</ Sayfa>

4. Adım: Vendor/Module/Block/CaptchaForm.php

ad alanı Satıcı \ Modülü \ Blok;


sınıf CaptchaForm \ Magento \ Framework \ Görünüm \ Eleman \ Şablon genişletir
{
    public işlevi getFormAction ()
    {
        $ $ this-> getUrl ('yourroute / index / post', ['_secure' => true]);
    }
}

Adım 5: Vendor/Moduel/view/frontend/templates/captchaform.phtml

<form class = "form contact"
      action = "<? php / * @escapeNotVerified * / echo $ block-> getFormAction ();?>"
      id = "temas biçimli"
      yöntem = "post"
      data-hasrequired = "<? php / * @escapeNotOnaylanmış * / echo __ ('* Zorunlu Alanlar')?>"
      Veri-Mage-init = '{ "doğrulama" {}}'>
    <fieldset class = "fieldset">
        <legend class = "legend"> <span> <? php / * @escapeNotOnaylanmış * / echo __ ('Bize Yazın')?> </span> </legend> <br />

        <div class = "alan adı gerekli">
            <label class = "label" = "name"> <span> <? php / * @escapeNotOnaylanmış * / echo __ ('Name')?> </span> </label>
            <div class = "control">
                <input name = "name" id = "name" title = "<? php / * @escapeNotOnaylanmış * / echo __ ('Ad')?>" "değer =" "sınıf =" giriş metni "tür =" metin " veri doğrulamak = "{gerekli: gerçek}" />
            </ Div>
        </ Div>
        <div class = "alan e-postası gerekli">
            <label class = "label" = "email"> <span> <? php / * @escapeNotOnaylanmış * / echo __ ('E-posta')?> </span> </label>
            <div class = "control">
                <input name = "email" id = "email" title = "<? php / * @escapeNotOnaylanmış * / echo __ ('E-posta')?>" "value =" "class =" input-text "type =" email " data-validate = "{gerekli: doğru, 'validate-email': true}" />
            </ Div>
        </ Div>
        <? php echo $ block-> getChildHtml ('form.additional.info'); ?>
    </ Fieldset>
    <div class = "actions-toolbar">
        <div class = "birincil">
            <input type = "hidden" name = "hideit" id = "hideit" value = "" />
            <button type = "Gönder" title = "<? php / * @escapeNotOnaylanmış * / echo __ ('Gönder')?>" "=" eylemi birincil gönder ">
                <span> <? php / * @escapeNotOnaylanmış * / echo __ ('Gönder')?> </span>
            </ Düğmesi>
        </ Div>
    </ Div>
</ Form>

Artık captcha'yı formunuzda görebilirsiniz. Şimdi gözlemciyi kullanarak captcha'nızı onaylamanız gerekiyor. Bu yüzden doğrulama için post controller predispatch olayını kullanıyorum.

6. Adım: 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">
    <olay adı = "controller_action_predispatch_yourroute_index_post">
        <gözlemci adı = "captcha_custom_form" example = "Satıcı \ Modül \ Gözlemci \ CheckCustomFormObserver" />
    </ Etkinlik>
</ Config>

7. Adım: Vendor/Module/Observer/CheckCustomFormObserver.php

ad alanı Satıcı \ Modülü \ Gözlemci;

Magento \ Framework \ Event \ ObserverInterface;
Magento \ Framework \ App \ Request \ DataPersistorInterface;
Magento \ Framework \ App \ ObjectManager kullanın;
Magento \ Captcha \ Observer \ CaptchaStringResolver kullanın;

sınıf CheckCustomFormObserver ObserverInterface uygular
{
    / **
     * @var \ Magento \ Captcha \ Helper \ Data
     * /
    $ _helper korumalı;

    / **
     * @var \ Magento \ Framework \ App \ ActionFlag
     * /
    $ _actionFlag korumalı;

    / **
     * @var \ Magento \ Framework \ Message \ ManagerInterface
     * /
    $ messageManager korumalı;

    / **
     * @var \ Magento \ Framework \ App \ Response \ RedirectInterface
     * /
    $ yönlendirme korumalı;

    / **
     * @var CaptchaStringResolver
     * /
    korumalı $ captchaStringResolver;

    / **
     * @var DataPersistorInterface
     * /
    özel $ dataPersistor;

    / **
     * @param \ Magento \ Captcha \ Helper \ Data $ yardımcı
     * @param \ Magento \ Framework \ App \ ActionFlag $ actionFlag
     * @param \ Magento \ Framework \ Message \ ManagerInterface $ messageManager
     * @param \ Magento \ Framework \ App \ Response \ RedirectInterface $ yönlendirme
     * @param CaptchaStringResolver $ captchaStringResolver
     * /
    public işlev __construct (
        \ Magento \ Captcha \ Helper \ Data $ yardımcı,
        \ Magento \ Çerçeve \ Uygulama \ ActionFlag $ actionFlag,
        \ Magento \ Çerçeve \ Mesaj \ YöneticiInterface $ messageManager,
        \ Magento \ Framework \ App \ Response \ RedirectInterface $ yönlendirme,
        CaptchaStringResolver $ captchaStringResolver
    ) {
        $ this -> _ helper = $ yardımcı;
        $ this -> _ actionFlag = $ actionFlag;
        $ this-> messageManager = $ messageManager;
        $ this-> redirect = $ redirect;
        $ this-> captchaStringResolver = $ captchaStringResolver;
    }

    / **
     * Özel Formdaki CAPTCHA'yı kontrol edin
     *
     * @param \ Magento \ Framework \ Event \ Observer $ gözlemci
     * @return void
     * /
    public işlevi yürütme (\ Magento \ Framework \ Event \ Observer $ gözlemci)
    {
        $ formId = 'custom_form';
        $ captcha = $ this -> _ helper-> getCaptcha ($ formId);
        if ($ captcha-> isRequired ()) {
            / ** @var \ Magento \ Çerçeve \ Uygulama \ İşlem \ Eylem \ İşlem $ denetleyicisi * /
            $ controller = $ gözlemci-> getControllerAction ();
            if (! $ captcha-> isCorrect ($ this-> captchaStringResolver-> çözünür ($ controller-> getRequest (), $ formId))) {
                $ this-> messageManager-> addError (__ ('Yanlış CAPTCHA.'));
                $ this-> getDataPersistor () -> set ($ formId, $ controller-> getRequest () -> getPostValue ());
                $ this -> _ actionFlag-> set ('', \ Magento \ Framework \ App \ Eylem \ Eylem \ Eylem :: FLAG_NO_DISPATCH, doğru);
                $ this-> redirect-> redirect ($ controller-> getResponse (), 'yourroute / index / index');
            }
        }
    }

    / **
     * Veri Persistörü Alın
     *
     * @return DataPersistorInterface
     * /
    özel işlev getDataPersistor ()
    {
        if ($ this-> dataPersistor === null) {
            $ this-> dataPersistor = ObjectManager :: getInstance ()
                -> olsun (DataPersistorInterface :: sınıfı);
        }

        $ $ this-> dataPersistor;
    }
}

Çok detaylı. Ben deneyeceğim.
Paul,

@Sohel Rana ürün inceleme formuna nasıl eklenebilir
supriya mishra

@supriyamishra kontrol etmek gerekiyor
Sohel Rana

1
Merhaba captcha görüntüleniyor ama gözlemci controller_action_predispatch _ ** bu captcha doğrulanmadığı için çalışmadığını düşünüyorum
AbdulBasit

1
Yukarıdaki hatayı
çözdüm ama captcha'yı

1

Bunu işe alamayanlarınız için yaptığım şeyi yapmanız gerekebilir:

Captcha'nın görüntülenmemesinin nedeni, temel ayarların, _toHtml dosyasında captcha'nın gerekli olup olmadığını görmek için bir kontrol yapan Varsayılan captcha bloğunu kullanmasıdır.

Captcha için her zaman gösterme ayarlarınız varsa, muhtemelen bu sorunla karşılaşmadınız, ancak her zaman captcha'ları gösterecek şekilde ayarlanmadıysa ve gerek duyduğunuzdan her zaman captcha'ları (örneğin, hesap oluştur / giriş yap) göstermek istemiyorsanız mantığını sadece özel mesaj kodunun "Her zaman gerekli" olarak ayarla

satıcının 69 satırında / magento / module-captcha / Block / Captcha / DefaultCaptcha.php göreceksiniz:

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

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

$this->getCaptchaModel()aramaları $this->_captchaData->getCaptcha()olduğu satıcı / magento / modül kaptan / Yardımcı / 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];
}

Burada getCaptcha yöntemi, oluşturulacak captcha tipi için config değerini kontrol eder ve fabrikasını içine yükler. $this->_factory->create()

Ancak bu fabrika sınıfına girdiğinizde göreceksiniz

 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;
}

Buradaki sorun, fabrikanın herhangi bir Fabrika modeli için Magento Captcha modülünde neye bakacağının önemi yok.

Yardımcının çevresine sarılacak bir eklenti oluşturmalı ve form anahtarımızı kontrol etmeliyiz ve eğer bizim form anahtarımız kullanılıyorsa, \ Magento \ Captcha \ Model \ DefaultModel ve overides modelini taşıyan yeni bir fabrika sınıfı oluşturmalıyız. isRequired () yöntemi. Bu gibi görünen bir şey:

içinde \ Sizin \ Modülü \ vb \ 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>

içinde Sizin \ Modülü \ Eklenti \ Yardımcısı \ CaptchaData

<?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);

}

}

içinde senin \ Modülü \ Modeli \ 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;
}
}

ve son olarak, modelinizi aşmak için modeliniz \ Sizin \ Modül \ Model \ Captcha :

<?php

namespace Your\Module\Model;

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

0

Haber bülteni abone sayfasında captcha'ya ihtiyacım var, bu yüzden benim için haber bülteni gözlemcisi ve captcha çalışması kullandım.

1) uygulama / kod / 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) 'Yönetici -> Mağazalar -> Yapılandırma -> Müşteri -> Müşteri Yapılandırması -> Captcha' seçeneğine gidin ve yapılandırın. 'Bülten Formu' değerinde yeni formlar görebilirsiniz.

3) mizanpaj dosyasını temada kopyala (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) Gözlemci oluştur -> app / code / Vendorname / Modulename / etc / frontend'de event.xml dosyasını oluşturun

 <?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) Gözlemci modeli oluşturun ve captcha uygulamasını / kodunu / Vendorname / Modulename / Observer / CheckCustomFormObserver.php dosyasını kontrol edin.

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);
                }
            }
        }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.