Как переопределить контроллер в Magento2?

Я хочу переопределить поведение контроллера существующего модуля Magento/*. Я хочу создать свою собственную Magento/Customer/Controller/Account/LoginPost.php-реализацию.

  1. Как я могу это сделать?
  2. Внедрение зависимостей кажется хорошей вещью для классов моделей, но как насчет контроллеров? Могу ли я где-нибудь внедрить свой собственный класс контроллера LoginPost, чтобы какой-то объект использовал мою собственную реализацию?

person wit0ld    schedule 15.04.2015    source источник
comment
Если бы я мог использовать маршрутизатор, чтобы просто направить клиента/учетную запись/loginPost в мой контроллер, было бы неплохо. Но опять же, как определить это в route.xml?   -  person wit0ld    schedule 16.04.2015


Ответы (2)


Вы можете использовать плагины Magento2. для этого.

Magento позволяет изменять или расширять поведение любого исходного общедоступного метода в любом классе Magento. Вы можете изменить поведение исходного метода, создав расширение. Эти расширения используют класс Plugin и поэтому называются подключаемыми модулями.

Напишите следующее в файле app/code/YourNamespace/YourModule/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">    
   <type name="Magento\Customer\Controller\Account\LoginPost">
       <plugin name="yourModuleAccountLoginPost" type="YourNamespace\YourModule\Plugin\Customer\LoginPost" sortOrder="10" disabled="false"/>
   </type>
</config>

Создайте новый файл с именем app/code/YourNamespace/YourModule/Plugin/Customer/LoginPost.php и напишите в нем следующий код:

<?php

    namespace YourNamespace\YourModule\Plugin\Customer;

    class LoginPost
    {
        public function aroundExecute(\Magento\Customer\Controller\Account\LoginPost $subject, \Closure $proceed)
        {
            // your custom code before the original execute function
            $this->doSomethingBeforeExecute();

            // call the original execute function
            $returnValue = $proceed();

            // your custom code after the original execute function
            if ($returnValue) {
                $this->doSomethingAfterExecute();
            }

            return $returnValue;
        }
    }
?>

Точно так же вы также можете использовать функции beforeExecute() и afterExecute() в приведенном выше классе. Подробности смотрите по этой ссылке. .

person Mukesh Chapagain    schedule 15.05.2016

Я нашел решение после некоторого расследования ;-).

Этот ресурс был очень полезен: https://github.com/tzyganu/Magento2SampleModule.

Пример модуля для этого решения находится здесь: https://github.com/nuclearhead/M2OverrideAction.

В результате, если вы перейдете к URI /customer/account/login, будет запущен метод из пользовательского модуля вместо метода по умолчанию из модуля Magento_Customer, а URL-адрес останется прежним. Конечно, вы можете сделать то же самое с действием loginPost.

Я сделал это с переопределением класса Router в di.xml. Я упростил версию модуля SampleNews от tzyganu, чтобы прояснить решение. Класс Router проверяет, какой URI возвращает метод $request->getPathInfo(), а затем устанавливает новые конфиги в $request:

$request->setModuleName('overrideaction')
      ->setControllerName('view')
      ->setActionName('index');
$request->setDispatched(true);
$this->dispatched = true;
return $this->actionFactory->create(
    'Magento\Framework\App\Action\Forward',
    ['request' => $request]
);

etc/frontend/di.xml моего пользовательского модуля:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\App\RouterList">
        <arguments>
            <argument name="routerList" xsi:type="array">
                <item name="customer" xsi:type="array">
                    <item name="class" xsi:type="string">MiniSamples\OverrideAction\Controller\Router</item>
                    <item name="disable" xsi:type="boolean">false</item>
                    <item name="sortOrder" xsi:type="string">9</item>
                </item>
            </argument>
        </arguments>
    </type>
</config>
person wit0ld    schedule 22.04.2015