【问题标题】:How to override Controller in Magento2?如何覆盖 Magento2 中的控制器?
【发布时间】:2015-04-15 15:42:16
【问题描述】:

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

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

【问题讨论】:

  • 如果我可以使用路由器将客户/帐户/loginPost 路由到我的控制器中,那就太好了。但同样,如何在 routes.xml 中定义它?

标签: magento2


【解决方案1】:

您可以为此使用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() & afterExecute() 函数。详情请查看this link

【讨论】:

    【解决方案2】:

    经过一番调查,我找到了解决方案 ;-)。

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

    此解决方案的示例模块在这里: https://github.com/nuclearhead/M2OverrideAction

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

    我使用di.xml 中的Router 类覆盖来做到这一点。我简化了 tzyganu 的 SampleNews 模块版本以阐明解决方案。 Router 类检查返回 $request-&gt;getPathInfo() 方法的 URI,然后将新配置设置为 $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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-29
      • 2017-02-19
      • 2016-11-19
      • 2019-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多