Question

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

Was it helpful?

Solution

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.

OTHER TIPS

Since Magento only needs to know the module name to find the path to a matching controller,

Change:

<MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension_Catalog_ProductController</MyOne_MyExtension>

to:

<MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension</MyOne_MyExtension>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top