I want to overload the saveAction method from the core/Mage/Adminhtml/controllers/Catalog/ProductController.php and it won’t work - I have now searched and tried for a complete day :(
Background: I want to change the value of a custom attribute before the saving of the product. I found out, that the _initProductSave sets the attributes and I think, that changing them after the init_ProductSave would be a good point (if anyone knows a better place, please let me know) ...
MAY ANYONE PLEASE HELP ME ... :)
Magento Version: Community Edition version 1.7.0.1 No Extension, no themes installed, I just installed this version completely blank ...
VERSION 1: Overwritting the controller by copying to the local/Mage folder
First of all I tried to copy the file to the app/code/local folder, within the correct struture - but it won't work (I have done this with the Varient.php for local testsystem and the stores.php for correcting the price bug - for both it's working ...)
VERSION 2: Overwritting the controller with an extension
My extension looks like this:
File structure:
code/local/MyOne/MyExtension/controllers/Catalog/ProductController.php
code/local/MyOne/MyExtension/etc/config.xml
etc/modules/MyOne_MyExtension.xml
The files look the following: MyOne_MyExtension.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<MyOne_MyExtension>
<active>true</active>
<codePool>local</codePool>
</MyOne_MyExtension>
</modules>
</config>
code/local/MyOne/MyExtension/etc/config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<MyOne_MyExtension>
<version>1.0.0</version>
</MyOne_MyExtension>
</modules>
<admin>
<routers>
<adminhtml>
<args>
<modules>
<MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension_Catalog_ProductController</MyOne_MyExtension>
</modules>
</args>
</adminhtml>
</routers>
</admin>
</config>
and the last one, code/local/MyOne/MyExtension/controllers/Catalog/ProductController.php:
<?php
require_once 'Mage/Adminhtml/controllers/Catalog/ProductController.php';
class MyOne_MyExtension_Catalog_ProductController extends Mage_Adminhtml_Catalog_ProductController
{
public function saveAction()
{
// do my stuff
die('reached method');
// after pressing on save, there should no be a white screen ...
}
}
?>
I have googled and read that much, I do not see an error ...
Any help would really be great !!!
Greetings, matthias
NB: Given the method being targeted...
Mage_Adminhtml_Catalog_ProductController->_initProductSave()
...it would be best practice to rule out the use of an adminhtml-scoped observer consuming the catalog_product_save_before
event.
"First of all I tried to copy the file to the app/code/local folder, within the correct structure..."
This is not an uncommon developer approach, but it will never work. Magento action controller classes are not loaded by the autoloader. They are explicitly loaded by their real filesystem path. Therefore, the so-called "include path hack" does not apply.
Ref. Mage_Core_Controller_Varien_Router_Standard->getControllerFileName()
.
Your second approach - performing a rewrite with a proper custom extension - is the correct approach. All you need is to understand how Magento finds action controller directories and matches action controller classes to the request URL.
In its config.xml, the Mage_Adminhtml
module configures the Admin router, which is responsible for matching all admin-related requests:
<admin>
<routers>
<adminhtml>
<use>admin</use>
<args>
<module>Mage_Adminhtml</module>
<frontName>admin</frontName>
</args>
</adminhtml>
</routers>
</admin>
The preceding configuration snippet does two things: the <frontName />
node adds a module route, and the <module />
node - along with the registered Mage_Adminhtml
<codePool />
value ("core") - establishes a directory in which action controller class may be found, in this case, /[basepath]/app/code/core/Mage/Adminhtml/controllers/
.
Module action controller rewrites work by adding other candidate matching directories to an existing module route. This is all parsed from the configuration:
<admin>
<routers>
<adminhtml>
<args>
<modules>
<MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension_Catalog_ProductController</MyOne_MyExtension>
</modules>
</args>
</adminhtml>
</routers>
</admin>
As can be seen, the above configuration simply adds or adds to the admin/routers/adminhtml/args/
node when the configuration XML is compiled. How this is interpreted and used for request matching is quite similar to the "normal" process of controller matching. In the above example, the MyOne_MyExtension
module is effectively adding a directory to the list of directories for the Adminhtml module. Assuming it's in the local
codePool, the above example points to the directory
/[basepath]/app/code/local/MyOne/MyExtension/controllers/Catalog/ProductController/
This would work if there were an action controller class at
/[basepath]/app/code/local/MyOne/MyExtension/controllers/Catalog/ProductController/Catalog/ProductController.php
which contained a _initProductSave()
method in a class named
MyOne_MyExtension_Catalog_ProductController_Catalog_ProductController
Hopefully this explanation is enough to see that config-based controller rewrites work at the directory level, rather than by specifying a particular class (which is how block, helper, and model rewrites work). Because this configuration adds a directory, it doesn't have to result in a rewrite, as it can be used to simply add new actions for a given module. Ultimately, an action controller rewrite only occurs if some other controller class matches before the "original" controller class.