Antworten:
Sie müssen einige Schritte ausführen, um Magento Captcha in ein benutzerdefiniertes Modul zu integrieren.
Schritt 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"> <default> <Kunde> <captcha> <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"> <Frontend> <areas> <custom_form> <label> Benutzerdefiniertes Formular </ label> </ custom_form> </ areas> </ frontend> </ captcha> </ default> </ config>
Schritt 2: Gehen Sie zu " Admin -> Stores -> Configuration -> Customer -> Customer Configuration -> Captcha " und konfigurieren Sie. Sie können den neuen Formularwert "Benutzerdefiniertes Formular" sehen.
Schritt 3: Erstellen 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 = "urne: magento: framework: View / Layout / etc / page_configuration.xsd"> <head> <title> Benutzerdefiniertes Formular </ title> </ head> <body> <referenceContainer name = "content"> <block class = "Vendor \ Module \ Block \ CaptchaForm" name = "contactForm" template = "Vendor_Module :: captchaform.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"> benutzerdefinierte_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>
Schritt 4: Vendor/Module/Block/CaptchaForm.php
Namespace Vendor \ Module \ Block; Die Klasse CaptchaForm erweitert \ Magento \ Framework \ View \ Element \ Template { öffentliche Funktion getFormAction () { return $ this-> getUrl ('yourroute / index / post', ['_secure' => true]); } }
Schritt 5: Vendor/Moduel/view/frontend/templates/captchaform.phtml
<form class = "Kontaktformular" action = "<? php / * @escapeNotVerified * / echo $ block-> getFormAction ();?>" id = "Kontaktformular" method = "post" data-hasrequired = "<? php / * @escapeNotVerified * / echo __ ('* Erforderliche Felder')?>" data-mage-init = '{"validation": {}}'> <fieldset class = "fieldset"> <legend class = "legend"> <span> <? php / * @escapeNotVerified * / echo __ ('Write Us')?> </ span> </ legend> <br /> <div class = "Feldname erforderlich"> <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 = "Feld E-Mail erforderlich"> <label class = "label" für = "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 = "{Erforderlich: 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>
Jetzt können Sie Captcha in Ihrem Formular sehen. Jetzt müssen Sie Ihr Captcha mit Observer validieren. Daher verwende ich das Post-Controller-Predispatch-Ereignis zur Validierung.
Schritt 6: Vendor/Module/etc/frontend/events.xml
<? xml version = "1.0"?> <config xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: noNamespaceSchemaLocation = "urne: magento: framework: Ereignis / etc / events.xsd"> <event name = "controller_action_predispatch_yourroute_index_post"> <observer name = "captcha_custom_form" instance = "Anbieter \ Modul \ Observer \ CheckCustomFormObserver" /> </ event> </ config>
Schritt 7: Vendor/Module/Observer/CheckCustomFormObserver.php
Namespace Vendor \ Module \ Observer; Verwenden Sie Magento \ Framework \ Event \ ObserverInterface. Verwenden Sie Magento \ Framework \ App \ Request \ DataPersistorInterface. Verwenden Sie Magento \ Framework \ App \ ObjectManager. Verwenden Sie Magento \ Captcha \ Observer \ CaptchaStringResolver. Klasse CheckCustomFormObserver implementiert ObserverInterface { / ** * @var \ Magento \ Captcha \ Helper \ Data * / protected $ _helper; / ** * @var \ Magento \ Framework \ App \ ActionFlag * / protected $ _actionFlag; / ** * @var \ Magento \ Framework \ Message \ ManagerInterface * / protected $ messageManager; / ** * @var \ Magento \ Framework \ App \ Response \ RedirectInterface * / protected $ 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 * / public function __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; } / ** * Aktivieren Sie CAPTCHA im benutzerdefinierten Formular * * @param \ Magento \ Framework \ Event \ Observer $ observer * @return void * / public function 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 (__ ('Falsches 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'); } } } / ** * Holen Sie sich Data Persistor * * @return DataPersistorInterface * / private Funktion getDataPersistor () { if ($ this-> dataPersistor === null) { $ this-> dataPersistor = ObjectManager :: getInstance () -> get (DataPersistorInterface :: class); } return $ this-> dataPersistor; } }
Für diejenigen von Ihnen, die dies nicht zum Laufen bringen können, müssen Sie möglicherweise das tun, was ich getan habe:
Der Grund, warum Sie das Captcha möglicherweise nicht anzeigen, ist, dass die Grundeinstellungen den Block Standard-Captcha verwenden, der im _toHtml prüft, ob das Captcha erforderlich ist.
Wenn Sie Einstellungen haben, damit Captcha immer angezeigt wird, ist dieses Problem wahrscheinlich nicht aufgetreten. Wenn jedoch nicht festgelegt ist, dass Captchas immer angezeigt werden, und Sie nicht immer Captchas anzeigen möchten (dh Konto erstellen / anmelden usw.), müssen Sie dies tun Setzen Sie die Logik nur für Ihr benutzerdefiniertes Captcha auf "Immer erforderlich".
In Zeile 69 des Herstellers / magento / module-captcha / Block / Captcha / DefaultCaptcha.php sehen Sie:
/**
* Renders captcha HTML (if required)
*
* @return string
*/
protected function _toHtml()
{
if ($this->getCaptchaModel()->isRequired()) {
$this->getCaptchaModel()->generate();
return parent::_toHtml();
}
return '';
}
$this->getCaptchaModel()
ruft das auf, $this->_captchaData->getCaptcha()
was sich in
vendor / magento / module-captcha / Helper / Data.php befindet
/**
* 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];
}
Hier überprüft die Methode getCaptcha den Konfigurationswert für den Typ des zu rendernden Captcha und lädt dessen Factory mit $this->_factory->create()
Wenn Sie jedoch in diese Fabrikklasse eintreten, werden Sie sehen
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;
}
Das Problem hierbei ist, dass im Magento Captcha-Modul für jedes Factory-Modell unabhängig von der Fabrik das Aussehen gewählt wird
Wir müssen ein Plugin erstellen, das den Helfer umschließt und nach unserem Formularschlüssel sucht. Wenn unser Formularschlüssel verwendet wird, müssen wir eine neue Factory-Klasse erstellen, die unser Modell lädt, das \ Magento \ Captcha \ Model \ DefaultModel und darüber hinaus erweitert Die Methode isRequired (). Etwas, das so aussieht:
in \ Ihr \ Modul \ 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>
in Ihrem \ 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);
}
}
in \ Ihr \ Modul \ Modell \ 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;
}
}
und schließlich Ihr Modell, um die erforderlichen Parameter in \ Your \ Module \ Model \ Captcha zu überschreiben :
<?php
namespace Your\Module\Model;
class Captcha extends \Magento\Captcha\Model\DefaultModel
{
public function isRequired($login = null)
{
return true;
}
}
Ich brauche ein Captcha auf der Newsletter-Abonnenten-Seite, danke sohan, ich wurde als Newsletter-Beobachter verwendet und Captcha-Arbeit auf der Newsletter-Seite für mich.
1) app / code / Vendorname / Modulname / 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) Gehen Sie zu "Admin -> Stores -> Configuration -> Customer -> Customer Configuration -> Captcha" und konfigurieren Sie. Sie können den neuen Formularwert "Newsletter-Formular" sehen.
3) kopiere die Layoutdatei in das Theme (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) Beobachter erstellen -> Datei event.xml in app / code / Vendorname / Modulname / etc / frontend erstellen
<?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) Beobachter-Modell erstellen und Captcha-App / Code / Vendorname / Modulname / Observer / CheckCustomFormObserver.php prüfen
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);
}
}
}