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