当我将一些core/Mage/Adminhtml/Block/
文件复制到local/Mage/Adminhtml/Block/
一切正常时,但如果我将控制器复制到local/Mage/Adminhtml/controllers
- 核心控制器仍然可以工作并且系统看不到我的本地/ ...控制器。
1 回答
这是因为控制器的加载方式与其他类型类不同。你不能通过引用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;
}
然后让我们看一下Mage_Core_Model_Config::getModuleDir()
方法(内部引用了配置类Mage::getModuleDir()
):
public function getModuleDir($type, $moduleName)
{
$codePool = (string)$this->getModuleConfig($moduleName)->codePool;
$dir = $this->getOptions()->getCodeDir().DS.$codePool.DS.uc_words($moduleName, DS);
(...)
}
如您所见,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> -->
接下来,在 app/code/local/MyNamespace/MyModule/controllers 中的模块中创建一个控制器。将其命名为与正在重写的控制器相同。您必须使用与 Magento 相同的文件夹结构。在我们的例子中,我们创建了一个OnepageController.php
in 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
}
}
就是这样!请注意,您需要在执行此操作后刷新 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>
请注意,控制器路径已更改为MyNamespace_MyModule_Adminhtml
但不包含controllers
.
Magento 将自动查找具有相同相对路径和控制器名称的控制器。