如何在Magento2中覆盖Controller?

时间:2015-04-15 15:42:17

标签: magento2

我想覆盖现有Magento/*模块的Controller行为。我想创建自己的Magento/Customer/Controller/Account/LoginPost.php - 实现。

  1. 我该怎么做?
  2. 依赖注入似乎对模型类来说是好事但是控制器呢?我可以在某处注入自己的LoginPost控制器类,以便某些对象可以使用我自己的实现吗?

2 个答案:

答案 0 :(得分:4)

您可以使用Magento2's Plugins功能。

  

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()&amp; afterExecute()函数在上面的类中。有关详细信息,请查看http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html

答案 1 :(得分:3)

我经过一些调查后找到了解决办法;-)。

此资源非常有用:https://github.com/tzyganu/Magento2SampleModule

此解决方案的示例模块位于: https://github.com/nuclearhead/M2OverrideAction

效果是,如果你转到URI:/ customer / account / login:来自自定义模块的方法将被触发而不是来自Magento_Customer模块的默认方法,并且URL将保持不变。当然,您可以使用loginPost操作执行相同的操作。

我在di.xml中使用Router类覆盖来完成此操作。我简化了tzyganu的SampleNews模块版本以澄清解决方案。 Router类检查哪些URI返回$ request-&gt; 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>