问题描述
当我将某些core/Mage/Adminhtml/Block/
文件复制到local/Mage/Adminhtml/Block/
时,一切正常,但是如果我将控制器复制到local/Mage/Adminhtml/controllers
-核心控制器仍然可以工作,并且系统看不到我的local/...控制器.
When I copy some core/Mage/Adminhtml/Block/
files to local/Mage/Adminhtml/Block/
everything work's fine, but if I copy controller to local/Mage/Adminhtml/controllers
- core controller still works and system don't see my local/ ... controller.
推荐答案
这是因为控制器以与其他类型类不同的方式加载.您不能通过引用Mage
类来做到这一点.要了解它们的加载方式,让我们看一下标准的Magento路由器及其方法getControllerFileName()
:
It's because controllers are loaded in a different way than other type classes. You don't do it by referencing to Mage
class. To know how they are loaded lets look at a standard Magento router and its method 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()
内部引用了配置类):
Then lets look at Mage_Core_Model_Config::getModuleDir()
method (config class is referenced inside 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获得了实际的模块代码池.这就是为什么简单的副本不起作用的原因.您必须重写控制器.
As you can see, Magento get real module code pool in this case. That's why simple copy won't work. You have to rewrite controllers.
如果您不知道如何正确地重写控制器,请在评论中告诉我.我将相应地更新此答案.
If you don't know how to properly rewrite a controller let me know in the comments. I will update this answer accordingly.
编辑
要重写控制器,您需要在本地代码池中创建一个新模块(或使用现有模块).如果您不知道如何创建模块,请查看此 SO主题.假设您要重写Magento Onepage结帐控制器.
To rewrite a controller you need to create a new module in local code pool (or use existing one). If you don't know how to create a module check this SO topic. Lets assume that you want to make a rewrite of Magento Onepage checkout controller.
在模块的config.xml中添加以下内容:
In config.xml of a module add this:
<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相同的文件夹结构.在我们的例子中,我们在controllers文件夹中创建一个OnepageController.php
.
Next, create a controller in your module in app/code/local/MyNamespace/MyModule/controllers. Name it the same as controller that is being rewritten. You must use the same folder structure as Magento use. In our case we create a OnepageController.php
in controllers folder.
//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>
,就可以了.通常,将管理员控制器放置在controllers
文件夹的Adminhtml
子文件夹中是一个好习惯.因此,示例config.xml将如下所示:
And that's it! Note that you need to flush Magento cache after doing this. Admin controllers are very similar to rewrite. Just change a <frontend>
to <admin>
and you're good to go. Usually it's a good practice to place admin controllers to Adminhtml
subfolder of controllers
folder. So example config.xml would look like this:
<admin>
<routers>
<adminhtml>
<args>
<modules>
<mynamespace_mymodule before="Mage_Checkout">MyNamespace_MyModule_Adminhtml</mynamespace_mymodule>
</modules>
</args>
</adminhtml>
</routers>
</admin>
请注意,控制器路径已更改为MyNamespace_MyModule_Adminhtml
,但其中不包含controllers
.
Note that controller path has changed to MyNamespace_MyModule_Adminhtml
but it does not contain controllers
.
Magento将自动查找具有相同相对路径和控制器名称的控制器.
Magento will automatically look to controllers with the same relative path and controller name.
这篇关于Magento将控制器复制到本地的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!