Answers:
您需要按照一些步骤将magento验证码用于自定义模块。
步骤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 translation =“ 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”> <头> <title>自定义表单</ title> </ head> <身体> <referenceContainer name =“ content”> <block class =“ Vendor \ Module \ Block \ CaptchaForm” name =“ contactForm”模板=“ Vendor_Module :: captchaform.phtml”> <container name =“ form.additional.info” label =“表单其他信息”> <block class =“ Magento \ Captcha \ Block \ Captcha” name =“验证码” 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>
第四步: Vendor/Module/Block/CaptchaForm.php
命名空间Vendor \ Module \ Block; CaptchaForm类扩展\ Magento \ Framework \ View \ Element \ Template { 公共函数getFormAction() { 返回$ 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 __('*必填字段')?>” data-mage-init ='{“验证”:{}}'> <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 =“必填字段电子邮件”> <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>
现在您可以在表单中看到验证码了。现在需要使用观察者来验证您的验证码。因此,我使用控制器后预调度事件进行验证。
步骤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 * / 受保护的$ _actionFlag; / ** * @var \ Magento \ Framework \ Message \ ManagerInterface * / 受保护的$ messageManager; / ** * @var \ Magento \ Framework \ App \ Response \ RedirectInterface * / 受保护的$ redirect; / ** * @var CaptchaStringResolver * / 受保护的$ captchaStringResolver; / ** * @var DataPersistorInterface * / 私人$ dataPersistor; / ** * @参数\ Magento \ Captcha \ Helper \ Data $ helper * @param \ Magento \ Framework \ App \ ActionFlag $ actionFlag * @param \ Magento \ Framework \ Message \ ManagerInterface $ messageManager * @param \ Magento \ Framework \ App \ Response \ RedirectInterface $ redirect * @参数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; } / ** *在自定义表单上检查验证码 * * @param \ Magento \ Framework \ Event \ Observer $ observer * @返回无效 * / 公共函数execute(\ Magento \ Framework \ Event \ Observer $ observer) { $ formId ='custom_form'; $ captcha = $ this-> _ helper-> getCaptcha($ formId); 如果($ captcha-> isRequired()){ / ** @var \ Magento \ Framework \ App \ Action \ Action $ controller * / $ controller = $ observer-> getControllerAction(); 如果(!$ captcha-> isCorrect($ this-> captchaStringResolver-> resolve($ controller-> getRequest(),$ formId))){ $ this-> messageManager-> addError(__('不正确的验证码。')); $ 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() { 如果($ this-> dataPersistor === null){ $ this-> dataPersistor = ObjectManager :: getInstance() ->获取(DataPersistorInterface :: class); } 返回$ this-> dataPersistor; } }
对于无法使用此功能的人,您可能需要做我做的事情:
您可能无法显示验证码的原因是,基本设置将使用默认验证码块,该代码在_toHtml中进行检查以查看是否需要验证码。
如果您已将验证码设置为始终显示,则可能未遇到此问题,但是,如果未将其设置为始终显示验证码,并且您不想始终显示验证码(即帐户创建/登录等),则不需要将仅您的自定义验证码的逻辑设置为“始终需要”。
在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方法检查要呈现的验证码类型的config值,并使用 $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模块中看起来是什么,.so
我们需要创建一个插件来包装帮助程序,并检查我们的表单密钥,如果正在使用我们的表单密钥,我们需要创建一个新的工厂类,以加载扩展了\ Magento \ Captcha \ Model \ DefaultModel并覆盖的模型 isRequired()方法。看起来像这样:
在\ 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>
在Your \ Module \ Plugin \ Helper \ 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);
}
}
在\ 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;
}
}
最后,您的模型可以覆盖\ Your \ Module \ Model \ Captcha中的必需参数 :
<?php
namespace Your\Module\Model;
class Captcha extends \Magento\Captcha\Model\DefaultModel
{
public function isRequired($login = null)
{
return true;
}
}
我需要在新闻订阅者页面中的验证码,谢谢sohan,我曾被新闻观察者和新闻页面中的验证码工作用过。
1)应用程序/代码/供应商名称/模块名称/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)创建观察者模型并检查验证码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);
}
}
}