覆盖社区扩展中的Magento控制器

时间:2013-04-04 14:54:15

标签: magento controller override

我在我的magento 1.7商店安装了扩展CreativeStyle CheckoutByAmazon,我试图覆盖CheckoutController类,但是magento似乎忽略了我的覆盖。任何建议将不胜感激。还清除缓存但仍然无法正常工作

(在app / code / local Folder中)

MyModule的   \ CheckoutByAmazon       \控制器           \ CheckoutController.php       \等等           \ config.xml中

(应用程序的/ etc / config.xml中)

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <MyModule_CheckoutByAmazon>
            <version>0.1.0</version>
        </MyModule_CheckoutByAmazon>
    </modules>
    <frontend>
        <routers>
            <checkoutbyamazon>
                <args>
                    <modules>
                        <MyModule_CheckoutByAmazon before="Creativestyle_CheckoutByAmazon">MyModule_CheckoutByAmazon</MyModule_CheckoutByAmazon>
                    </modules>
                </args>
            </checkoutbyamazon>
        </routers>
    </frontend>
</config>

(在app / code / local / MyModule / CheckoutByAmazon / controllers / CheckoutController中)

<?php
//Controllers are not autoloaded so we will have to do it manually:
require_once 'Creativestyle/CheckoutByAmazon/controllers/CheckoutController.php';

class MyModule_CheckoutByAmazon_CheckoutController extends Creativestyle_CheckoutByAmazon_CheckoutController {

    public function indexAction() {
       exit('I am here');
        parent::indexAction();
    }

    //i want to override this function
      public function saveShippingAction() {
       //insert my overriding code
        exit('saveShipping');
        }

}
?>

(在etc / modules / MyModule_CheckoutByAmazon.xml中)

<?xml version="1.0"?>
<config>
    <modules>
        <MyModule_CheckoutByAmazon>
            <active>true</active>
            <codePool>local</codePool>
        </MyModule_CheckoutByAmazon>
    </modules>
</config>

我哪里错了?

3 个答案:

答案 0 :(得分:9)

tl; dr:原始扩展程序配置可能是问题所在,但这是解决问题的方法。

为了开始调试,有必要了解您要做的事情。目前没有任何自定义模块,Magento将获取请求路径前缀“checkout”,将其匹配到 ./ app / code / core / Mage / Checkout / controllers / 目录,然后查找匹配项第二个和第三个参数作为该文件中的文件,类定义和该类中的操作方法的组合。非弃用的重写语法(您尝试使用模块执行)只需 添加一个用于匹配 的附加目录。在调试之前,最好涵盖基础知识。这为调试控制器覆盖提供了一个很好的机会。

必须满足许多前提条件(模块的 config.xml 合并,正确的语法和文件结构等)。最好先测试一下这些是否正常工作,因为它会减少并精确定位我们需要调试的区域。

在Magento根目录的 test.php 文件中,执行以下操作:

<?php
ini_set('display_errors',1);
error_reporting(E_ALL^E_STRICT);
include 'app/Mage.php';
Mage::setIsDeveloperMode(true);
Mage::app();

$origDir = Mage::getModuleDir('controllers','Creativestyle_CheckoutByAmazon').DS;
require_once $origDir.'CheckoutController.php';

$controller = new MyModule_CheckoutByAmazon_CheckoutController(
    Mage::app()->getRequest(),    //required constructor arg
    Mage::app()->getResponse()    //required constructor arg
);

echo get_class($controller);

访问yoursite.com/test.php,您应该会看到您的控制器类名称。如果你看到一个错误,或者你什么也看不到,那么相当低级的东西就会被打破。如果错误消息不直观,请检查您的模块配置是否正在合并并从那里移动。

如果类实例化,我们知道以下内容:

  1. 基本模块配置很好
  2. 文件结构适用于配置
  3. 明确的包含是好的
  4. 我怀疑你会做到这一点,因为我认为这个问题是基于配置的。有几种可能性。要获得洞察力,请将 test.php 修改为以下内容(假设PHP&gt; = 5.3):

    <?php
    ini_set('display_errors',1);
    error_reporting(E_ALL^E_STRICT);
    include 'app/Mage.php';
    Mage::setIsDeveloperMode(true);
    Mage::app();
    
    $router = Mage::app()->getFrontController()->getRouter('standard');
    /* @var $router Mage_Core_Controller_Varien_Router_Standard */
    
    $reflection = new ReflectionClass($router);
    $modules = $reflection->getProperty('_modules');
    $modules->setAccessible(true);
    
    var_dump($modules->getValue($router));
    

    输出应类似于以下内容:

    array(35) {
      ["core"]=>
      array(1) {
        [0]=>
        string(9) "Mage_Core"
      }
      ["install"]=>
      array(1) {
        [0]=>
        string(12) "Mage_Install"
      }
      ["directory"]=>
      array(1) {
        [0]=>
        string(14) "Mage_Directory"
      }
      // ...
      ["checkout"]=>
      array(2) {
        [0]=>
        string(25) "MyModule_CheckoutByAmazon"
        [1]=>
        string(13) "Mage_Checkout"
      }
      // ...
    }
    

    无论您在哪里看到多个子阵列,都会有一个控制器目录重写。

答案 1 :(得分:4)

要完成C4rter的回答,这里是您必须添加到config.xml文件中的完整代码:

<admin>
    <routers>
        <checkoutbyamazon>
            <args>
                <modules>
                    <MyModule_CheckoutByAmazon before="Creativestyle_CheckoutByAmazon_Adminhtml">MyModule_CheckoutByAmazon</MyModule_CheckoutByAmazon>
                </modules>
            </args>
        </checkoutbyamazon>
    </routers>
</admin>

您不需要前端重写部分。

答案 2 :(得分:2)

试图做同样的事也失败了。但我找到了原因。 CheckoutByAmazon扩展有一个同名的admincontroller:

<admin>
    <routers>
        <checkoutbyamazon>
            <use>admin</use>
            <args>
                <module>Creativestyle_CheckoutByAmazon</module>
                <frontName>checkoutbyamazon</frontName>
            </args>
        </checkoutbyamazon>
    </routers>
</admin>

所以你必须重写管理员控制器:

before="Creativestyle_CheckoutByAmazon_Adminhtml"