回答:
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; } }
これが機能しない場合は、私がしたことをする必要があります:
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;
}
}
ニュースレターの購読者ページに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);
}
}
}