Magento将控制器复制到本地

Lub*_*hal 1 php magento

当我复制一些core/Mage/Adminhtml/Block/文件到local/Mage/Adminhtml/Block/一切工作没关系,但如果我复制控制器local/Mage/Adminhtml/controllers- 核心控制器仍然工作,系统没有看到我的本地/ ...控制器.

Ven*_*tus 8

这是因为控制器的加载方式与其他类型不同.你不是通过引用Mage类来做到的.要知道他们是如何加载让我们来看看一个标准的Magento路由器及其方法getControllerFileName():


// Mage_Core_Controller_Varien_Router_Standard
public function getControllerFileName($realModule, $controller)
{
    $parts = explode('_', $realModule);
    $realModule = implode('_', array_splice($parts, 0, 2));
    $file = Mage::getModuleDir('controllers', $realModule);
    if (count($parts)) {
        $file .= DS . implode(DS, $parts);
    }
    $file .= DS.uc_words($controller, DS).'Controller.php';
    return $file;
}
Run Code Online (Sandbox Code Playgroud)

然后让我们看一下Mage_Core_Model_Config::getModuleDir()方法(内部引用了config类Mage::getModuleDir()):


public function getModuleDir($type, $moduleName)
{
    $codePool = (string)$this->getModuleConfig($moduleName)->codePool;
    $dir = $this->getOptions()->getCodeDir().DS.$codePool.DS.uc_words($moduleName, DS);

    (...)
}
Run Code Online (Sandbox Code Playgroud)

如您所见,Magento在这种情况下获得了真正的模块代码池.这就是为什么简单的副本不起作用的原因.你必须重写控制器.

如果您不知道如何正确重写控制器,请在评论中告诉我.我会相应地更新这个答案.

编辑

要重写控制器,您需要在本地代码池中创建一个新模块(或使用现有模块).如果您不知道如何创建模块,请查看 SO主题.让我们假设你想重写Magento Onepage结账控制器.

在模块的config.xml中添加:


<frontend>
    <routers>
        <checkout>
            <args>
                <modules>
                    <mynamespace_mymodule before="Mage_Checkout">MyNamespace_MyModule</mynamespace_mymodule>
                </modules>
            </args>
        </checkout>
    </routers>
</frontend>
<!-- rewrite of admin controllers are the same. instead of <frontend> use <admin> -->
Run Code Online (Sandbox Code Playgroud)

接下来,在app/code/local/MyNamespace/MyModule/controllers中的模块中创建一个控制器.将其命名为与正在重写的控制器相同.您必须使用与Magento使用相同的文件夹结构.在我们的例子中,我们创建一个OnepageController.phpin controllers文件夹.


//you have to manually include the controller being rewritten, because Magento autoloader cannot automatically resolve it.
require_once Mage::getModuleDir('controllers', 'Mage_Checkout') . DS . 'OnepageController.php';

class MyNamespace_MyModule_OnepageController extends Mage_Checkout_OnepageController
{
    //copy a method you want to rewrite, e.g.
    public function saveOrderAction()
    {
         //Method body
    }
}
Run Code Online (Sandbox Code Playgroud)

就是这样!请注意,执行此操作后需要刷新Magento缓存.管理控制器与重写非常相似.只需改变一个就<frontend>可以了<admin>,你很高兴.通常,将管理员控制器放在Adminhtml文件夹的子controllers文件夹中是一种很好的做法.所以示例config.xml看起来像这样:


<admin>
    <routers>
        <adminhtml>
            <args>
                <modules>
                    <mynamespace_mymodule before="Mage_Checkout">MyNamespace_MyModule_Adminhtml</mynamespace_mymodule>
                </modules>
            </args>
        </adminhtml>
    </routers>
</admin>
Run Code Online (Sandbox Code Playgroud)

请注意,控制器路径已更改为MyNamespace_MyModule_Adminhtml但不包含controllers.

Magento将自动查找具有相同路径和控制器名称的控制器.