Відповіді:
Вам потрібно виконати деякий крок для використання капсули magento в спеціальному модулі.
Крок 1 : Vendor/Module/etc/config.xml
<? xml version = "1.0"?> <config xmlns: xsi = "http://www.w3.org/2001/XMLSchema-in substance" xsi: noNamespaceSchemaLocation = "урна: magento: module: Magento_Store: etc / config.xsd"> <за замовчуванням> <клієнт> <captcha> <shown_to_logged_in_user> <custom_form> 1 </custom_form> </shown_to_logged_in_user> <завжди_для> <custom_form> 1 </custom_form> </always_for> </captcha> </customer> <captcha translate = "label"> <напередодні> <області> <custom_form> <label> Спеціальна форма </label> </custom_form> </areas> </frontend> </captcha> </default> </config>
Крок 2: Перейдіть на " Адміністратор -> Магазини -> Конфігурація -> Клієнт -> Конфігурація клієнта -> Captcha " та налаштуйте. Ви можете бачити значення нових форм "Спеціальна форма"
Крок 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 = "Постачальник \ Модуль \ Блок \ CaptchaForm" name = "contactForm" template = "Vendor_Module :: captchaform.phtml"> <ім'я контейнера = "form.additional.info" label = "Форма додаткової інформації"> <block class = "Magento \ Captcha \ Block \ Captcha" name = "captcha" after = "-" cacheable = "false"> <метод дії = "setFormId"> <argument name = "formId" xsi: type = "string"> custom_form </argument> </action> <метод дії = "setImgWidth"> <argument name = "width" xsi: type = "string"> 230 </argument> </action> <метод дії = "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
простір імен постачальник \ модуль \ блок; клас CaptchaForm розширюється \ Magento \ Framework \ Вид \ Елемент \ Шаблон { публічна функція getFormAction () { повернути $ this-> getUrl ('yourroute / index / post', ['_secure' => вірно]); } }
Крок 5: Vendor/Moduel/view/frontend/templates/captchaform.phtml
<form class = "контакт з формою" action = "<? php / * @escapeNotVerified * / echo $ block-> getFormAction ();?>" id = "контактна форма" method = "повідомлення" data-hasrequired = "<? php / * @escapeNotVerified * / echo __ ('* Обов'язкові поля')?>" data-mage-init = '{"валідація": {}}'> <fieldset class = "fieldset"> <legend class = "legend"> <span> <? php / * @escapeNotVerified * / echo __ ("Напишіть нам")?> </span> </legend> <br /> <div class = "потрібна назва поля"> <label class = "label" for = "name"> <span> <? php / * @escapeNotVerified * / echo __ ('Ім'я')?> </span> </label> <div class = "control"> <input name = "name" id = "name" title = "<? php / * @escapeNotVerified * / echo __ ('Ім'я')?>" value = "" class = "input-text" type = "text" data-validate = "{обов'язково: правда}" /> </div> </div> <div class = "поле електронної пошти потрібно"> <label class = "label" for = "email"> <span> <? php / * @escapeNotVerified * / echo __ ('Електронна пошта')?> </span> </label> <div class = "control"> <input name = "email" id = "email" title = "<? php / * @escapeNotVerified * / echo __ ('Електронна пошта')?>" value = "" class = "input-text" type = "email" data-validate = "{обов'язково: вірно," перевірити електронну пошту ": істина}" /> </div> </div> <? php echo $ block-> getChildHtml ('form.additional.info'); ?> </fieldset> <div class = "панель інструментів дій"> <div class = "основний"> <input type = "hidden" name = "hidit" id = "hidit" value = "" /> <button type = "submit" title = "<? php / * @escapeNotVerified * / echo __ (" Надіслати ")?>" class = "дія надіслати первинну"> <span> <? php / * @escapeNotVerified * / echo __ ('Надіслати')?> </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 = "урна: magento: Framework: подія / тощо / події.xsd"> <ім'я події = "контролер Managed_predispatch_yourroute_index_post"> <observer name = "captcha_custom_form" instance = "Постачальник \ Модуль \ Оглядач \ CheckCustomFormObserver" /> </event> </config>
Крок 7: Vendor/Module/Observer/CheckCustomFormObserver.php
простір імен постачальник \ модуль \ спостерігач; використовувати Magento \ Framework \ Event \ ObserverInterface; використовувати Magento \ Framework \ App \ Запит \ 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 * / захищений $ переадресація; / ** * @var CaptchaStringResolver * / захищений $ captchaStringResolver; / ** * @var DataPersistorInterface * / приватний $ 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 = $ помічник; $ this -> _ actionFlag = $ actionFlag; $ this-> messageManager = $ messageManager; $ this-> redirect = $ redirect; $ this-> captchaStringResolver = $ captchaStringResolver; } / ** * Перевірте CAPTCHA на спеціальній формі * * @param \ Magento \ Framework \ Подія \ спостерігач $ спостерігач * @return void * / виконання публічної функції (\ Magento \ Framework \ Event \ Observer $ observer) { $ formId = 'custom_form'; $ captcha = $ this -> _ helper-> getCaptcha ($ formId); if ($ captcha-> isRequired ()) { / ** @var \ Magento \ Framework \ Додаток \ Дія \ Контролер $ дій * / $ controller = $ observer-> getControllerAction (); if (! $ captcha-> isCorrect ($ this-> captchaStringResolver-> resolution ($ controller-> getRequest (), $ formId))) { $ this-> messageManager-> addError (__ ('Неправильна CAPTCHA.')); $ this-> getDataPersistor () -> set ($ formId, $ controller-> getRequest () -> getPostValue ()); $ this -> _ actionFlag-> set ('', \ Magento \ Framework \ App \ Action \ Action :: FLAG_NO_DISPATCH, правда); $ this-> redirect-> redirect ($ controller-> getResponse (), 'yourroute / index / index'); } } } / ** * Отримати персистор даних * * @return DataPersistorInterface * / приватна функція getDataPersistor () { if ($ this-> dataPersistor === null) { $ this-> dataPersistor = ObjectManager :: getInstance () -> отримати (DataPersistorInterface :: class); } повернути $ this-> dataPersistor; } }
Для тих із вас, хто не може змусити це працювати, можливо, вам доведеться зробити те, що я зробив:
Причина, яку ви не можете відображати в Captcha, полягає в тому, що базові параметри полягають у використанні блоку captcha за замовчуванням, який у _toHtml робить перевірку, щоб перевірити, чи потрібна вона.
Якщо у вас є налаштування для показу captcha завжди, ніж ви, ймовірно, не стикалися з цією проблемою, однак якщо він не налаштований завжди показувати captchas і ви не хочете завжди показувати капчу (тобто створення облікового запису / вхід і т.д.), ніж вам потрібно встановіть логіку лише для вашої власної капчу на "Завжди потрібно".
на лінії 69 постачальника / magento / module-captcha / Block / Captcha / DefaultCaptcha.php ви побачите:
/**
* 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 / module-captcha / Helper / 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 та overides метод isRequired () Щось так виглядає:
у \ Ваш \ Модуль \ тощо \ 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 на сторінці розсилки.
1) додаток / код / ім'я постачальника / ім'я модуля / тощо / 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) Перейдіть на "Адміністратор -> Магазини -> Конфігурація -> Клієнт -> Конфігурація клієнта -> Captcha" та налаштуйте. Ви можете побачити значення нових форм "Форма бюлетеня".
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) Створити спостерігача -> створити файл event.xml у додатку / код / Ім'я продавця / Ім'я модуля / тощо / frontend
<?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 / ім'я постачальника / ім'я модуля / спостерігача / 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);
}
}
}