Magento 2-キャプチャをカスタムフォームに追加する方法


28

フォーム送信を含むカスタムモジュールを開発しています。キャプチャを追加したいと思います。そして、キャプチャフォームが登録フォームのものと一致するように、Magentoのデフォルトのキャプチャライブラリを使用する必要があります。

回答:


35

magento captchaをカスタムモジュールに使用するには、いくつかの手順に従う必要があります。

ステップ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">
    <デフォルト>
        <お客様>
            <キャプチャ>
                <shown_to_logged_in_user>
                    <custom_form> 1 </ custom_form>
                </ shown_to_logged_in_user>
                <always_for>
                    <custom_form> 1 </ custom_form>
                </ always_for>
            </ captcha>
        </ customer>
        <captcha translate = "label">
            <フロントエンド>
                <エリア>
                    <custom_form>
                        <label>カスタムフォーム</ label>
                    </ custom_form>
                </ areas>
            </ frontend>
        </ captcha>
    </ default>
</ config>

ステップ2:「管理->ストア->構成->顧客->顧客の構成->キャプチャ」に移動して構成します。新しいフォームの値「カスタムフォーム」を表示できます

ステップ3:作成 Vendor/Module/view/frontend/layout/yourroutid_index_index.xml

<?xml version = "1.0"?>
<page xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" layout = "1column" xsi:noNamespaceSchemaLocation = "urn:magento:framework:View / Layout / etc / page_configuration.xsd">
    <head>
        <title>カスタムフォーム</ title>
    </ head>
    <本体>
        <referenceContainer name = "content">
            <block class = "Vendor \ Module \ Block \ CaptchaForm" name = "contactForm" template = "Vendor_Module :: captchaform.phtml">
                <container name = "form.additional.info" label = "フォームの追加情報">
                    <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>

ステップ4: Vendor/Module/Block/CaptchaForm.php

名前空間Vendor \ Module \ Block;


クラスCaptchaFormは\ Magento \ Framework \ View \ Element \ Templateを拡張します
{
    パブリック関数getFormAction()
    {
        return $ this-> getUrl( 'yourroute / index / post'、['_secure' => true]);
    }
}

ステップ5: Vendor/Moduel/view/frontend/templates/captchaform.phtml

<form class = "form contact"
      action = "<?php / * @escapeNotVerified * / echo $ block-> getFormAction();?>"
      id = "contact-form"
      method = "post"
      data-hasrequired = "<?php / * @escapeNotVerified * / echo __( '* Required Fields')?>"
      data-mage-init = '{"validation":{}}'>
    <fieldset class = "fieldset">
        <legend class = "legend"> <span> <?php / * @escapeNotVerified * / echo __( 'Write Us')?> </ span> </ legend> <br />

        <div class = "フィールド名が必要">
            <label class = "label" for = "name"> <span> <?php / * @escapeNotVerified * / echo __( 'Name')?> </ span> </ label>
            <div class = "control">
                <input name = "name" id = "name" title = "<?php / * @escapeNotVerified * / echo __( 'Name')?>" value = "" class = "input-text" type = "text" data-validate = "{required:true}" />
            </ div>
        </ div>
        <div class = "field email required">
            <label class = "label" for = "email"> <span> <?php / * @escapeNotVerified * / echo __( 'Email')?> </ span> </ label>
            <div class = "control">
                <input name = "email" id = "email" title = "<?php / * @escapeNotVerified * / echo __( 'Email')?>" value = "" class = "input-text" type = "email" data-validate = "{required:true、 'validate-email':true}" />
            </ div>
        </ div>
        <?php echo $ block-> getChildHtml( 'form.additional.info'); ?>
    </ fieldset>
    <div class = "actions-toolbar">
        <div class = "primary">
            <input type = "hidden" name = "hideit" id = "hideit" value = "" />
            <button type = "submit" title = "<?php / * @escapeNotVerified * / echo __( 'Submit')?>" class = "action submit primary">
                <span> <?php / * @escapeNotVerified * / echo __( 'Submit')?> </ span>
            </ button>
        </ div>
    </ div>
</ form>

これで、フォームにキャプチャを表示できるようになりました。オブザーバーを使用してキャプチャを検証する必要があります。そのため、検証にはポストコントローラーのpredispatchイベントを使用します。

ステップ6: 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>

ステップ7: Vendor/Module/Observer/CheckCustomFormObserver.php

名前空間Vendor \ Module \ Observer;

Magento \ Framework \ Event \ ObserverInterfaceを使用します。
Magento \ Framework \ App \ Request \ DataPersistorInterfaceを使用します。
Magento \ Framework \ App \ ObjectManagerを使用します。
Magento \ Captcha \ Observer \ CaptchaStringResolverを使用します。

クラスCheckCustomFormObserverはObserverInterfaceを実装します
{
    / **
     * @var \ Magento \ Captcha \ Helper \ Data
     * /
    保護された$ _helper;

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

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

    / **
     * @var \ Magento \ Framework \ App \ Response \ RedirectInterface
     * /
    保護された$ redirect;

    / **
     * @var CaptchaStringResolver
     * /
    protected $ captchaStringResolver;

    / **
     * @var DataPersistorInterface
     * /
    private $ dataPersistor;

    / **
     * @param \ Magento \ Captcha \ Helper \ Data $ helper
     * @param \ Magento \ Framework \ App \ ActionFlag $ actionFlag
     * @param \ Magento \ Framework \ Message \ ManagerInterface $ messageManager
     * @param \ Magento \ Framework \ App \ Response \ RedirectInterface $ redirect
     * @param CaptchaStringResolver $ captchaStringResolver
     * /
    パブリック関数__construct(
        \ Magento \ Captcha \ Helper \ Data $ helper、
        \ Magento \ Framework \ App \ ActionFlag $ actionFlag、
        \ Magento \ Framework \ Message \ ManagerInterface $ messageManager、
        \ Magento \ Framework \ App \ Response \ RedirectInterface $ redirect、
        CaptchaStringResolver $ captchaStringResolver
    ){
        $ this-> _ helper = $ helper;
        $ this-> _ actionFlag = $ actionFlag;
        $ this-> messageManager = $ messageManager;
        $ this-> redirect = $ redirect;
        $ this-> captchaStringResolver = $ captchaStringResolver;
    }

    / **
     *カスタムフォームでCAPTCHAを確認する
     *
     * @param \ Magento \ Framework \ Event \ Observer $ observer
     * @return void
     * /
    パブリック関数execute(\ Magento \ Framework \ Event \ Observer $ observer)
    {
        $ formId = 'custom_form';
        $ captcha = $ this-> _ helper-> getCaptcha($ formId);
        if($ captcha-> ​​isRequired()){
            / ** @var \ Magento \ Framework \ App \ Action \ Action $ controller * /
            $ controller = $ observer-> getControllerAction();
            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()、 'yourroute / index / index');
            }
        }
    }

    / **
     *データ永続化を取得
     *
     * @return DataPersistorInterface
     * /
    プライベート関数getDataPersistor()
    {
        if($ this-> dataPersistor === null){
            $ this-> dataPersistor = ObjectManager :: getInstance()
                -> get(DataPersistorInterface :: class);
        }

        return $ this-> dataPersistor;
    }
}

非常に詳細。試してみます。
ポール

@Sohelラナは、どのように製品レビューの形にそれを追加することができます
supriyaのミシュラ

@supriyamishraを確認する必要があります
ソヘルラナ

1
こんにちはキャプチャが表示されますが、このキャプチャが検証されていないとして、オブザーバーcontroller_action_predispatchは_ **私が働いていないと思いれる
AbdulBasit

1
私は、エラーの上に解決が、私は私のカスタムフォームでキャプチャを参照することはできません
ジャファルpinjar

1

これが機能しない場合は、私がしたことをする必要があります:

captchaが表示されないのは、基本設定が_toHtmlでcaptchaが必要かどうかを確認するデフォルトのcaptchaブロックを使用するためです。

キャプチャを常に表示するように設定している場合は、おそらくこの問題に遭遇しなかった可能性がありますが、キャプチャを常に表示するように設定されておらず、キャプチャを常に表示したくない場合(アカウント作成/ログインなど)カスタムキャプチャのみのロジックを「常に必要」に設定します。

vendor / magento / module-captcha / Block / Captcha / DefaultCaptcha.phpの 69行目に表示されます:

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

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

$this->getCaptchaModel()通話$this->_captchaData->getCaptcha()中にある ベンダー/ Magentoの/モジュールキャプチャ/ヘルパー/ 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];
}

ここで、getCaptchaメソッドはcaptchaのタイプの設定値をチェックしてレンダリングし、そのファクトリーをロードします $this->_factory->create()

ただし、このファクトリクラスにステップインすると、

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

ここでの問題は、工場がどんな工場モデルのMagento Captchaモジュールで何を見るかに関係ないということです。

ヘルパーをラップしてフォームキーをチェックするプラグインを作成する必要があります。フォームキーが使用されている場合は、\ Magento \ Captcha \ Model \ DefaultModelを拡張してオーバーライドするモデルをロードする新しいファクトリクラスを作成する必要がありますisRequired()メソッド。次のようなもの:

あなたの\モジュール\ 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>

あなたの\モジュール\プラグイン\ヘルパー\ 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);

}

}

あなたの\モジュール\モデル\ 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;
}
}

最後に、オーバーライドするモデルは\ Your \ Module \ Model \ Captchaの必須パラメーターです 。

<?php

namespace Your\Module\Model;

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

0

ニュースレターの購読者ページにcaptchaが必要です。おかげで、ニュースレターのオブザーバーとcaptchaがニュースレターページで使用されました。

1)app / code / 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)「管理者->ストア->構成->顧客->顧客構成->キャプチャ」に移動して構成します。新しいフォームの値「Newsletter Form」を表示できます。

3)テーマのレイアウトファイルをコピーする(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)オブザーバーを作成-> app / code / Vendorname / Modulename / etc / frontendにevent.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_newsletter_subscriber_new">
        <observer name="captcha_newletter_form" instance="Vendorname/Modulename/Observer\CheckCustomFormObserver" />
    </event>
</config>

5)オブザーバーモデルを作成し、captcha app / code / 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);
                }
            }
        }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.