I think it'd be interesting to know exactly what you're trying to accomplish, but I can give you a few pointers without knowing details:
In most cases if the method you're trying to reference does not use $this
, you can safely call it statically:
Mage_Checkout_Controller_Action::preDispatch()
But you should probably be doing this via a controller predispatch observer. Magento affords you the ability to do this in Mage_Core_Controller_Varien_Action
:
abstract class Mage_Core_Controller_Varien_Action
{
// [...]
public function preDispatch()
{
// [...]
if ($this->_rewrite()) {
return; // [What is the purpose if this?]
}
// [...]
// [This is where my event needs to be firing, but this code never gets
// executed because the controller is rewritten]
Mage::dispatchEvent(
'controller_action_predispatch_'.$this->getFullActionName(),
array('controller_action'=>$this)
);
}
// [...]
}
All you have to do is add the full action name onto the end of controller_action_predispatch
. An example of shoehorning functionality into Onepage Savebilling:
<events>
<controller_action_predispatch_checkout_onepage_saveBilling>
<observers>
<some_unique_name_for_this_event>
<class>yourmodel/observer</class>
<method>myPredispatchObserver</method>
</some_unique_name_for_this_event>
</observers>
</controller_action_predispatch_checkout_onepage_saveBilling>
</events>
What's more, in your observer method, you need to accept the observer and you can get the controller itself from getEvent
:
<?php
class MyCompany_MyModule_Model_Observer
{
public function myPredispatchObserver($observer)
{
$controller = $observer->getEvent()->getControllerAction();
}
}
Your customizations should be as easy to maintain as possible - especially for upgrades. This is likely best accomplished by identifying the best integration points and customizing core functionality when necessary.
When you rewrite a class via the configuration, you are changing the class instantiated, assumedly to customize a part of some core class behavior. This is more appropriate from a programmatic standpoint than owning the entire definition.
Rewrites won't work for parent classes or for library classes (e.g. Varien_Data_Collection_Db
), so changes to these must be implemented by transferrance to local code pool. I'm very curious to know what you want to change with the DB collection superclass.
While blocks, helpers, and models all have a similar xpath for rewriting, e.g.
global>[blocks|helpers|models]>[class group]>rewrite>[class id]
resource models require a slightly different mapping. I can tell you are using a pre-MDBM release of Magento (CE <1.6), so your rewrite mappings would be as follows:
<global>
<models>
<catalog>
<rewrite>
<layer_filter_attribute></layer_filter_attribute>
</rewrite>
</catalog>
<catalog_resource_eav_mysql4>
<rewrite>
<layer_filter_attribute></layer_filter_attribute>
<product_collection></product_collection>
</rewrite>
</catalog_resource_eav_mysql4>
</models>
</global>
As I said, I am quite curious to know your reasons for rewriting the resource models.
Best Answer
There are multiple approaches but I'll start with how it's not done to clarify some common misconceptions:
app/code/local
. This is because controller classes are not loaded byVarien_Autoload
, instead the files are explicitly included.<rewrite><controller><to>
syntax anymore. This is an old technique which is obsolete since Magento 1.3 (see: Overwriting controller vs overwriting action controller request)Add/override controller actions
To add controller actions to an existing controller, use the following in your config.xml:
Then create a controller in your module such as
You don't need to extend the original controller class because Magento will look in both classes, in the order defined by
before="..."
If you need to extend the original class because you want to reuse other methods from it, you have to include it (remember, controllers are not autoloaded):
Use observers to modify controller actions
If you don't add new actions, an alternative is to use observers to modify the behavior of existing actions. Every controller action triggers a dynamic "predispatch" event in the form
controller_action_predispatch_$FRONTNAME_$CONTROLLER_$ACTION
, for examplecontroller_action_predispatch_checkout_onepage_index
In the observer you have access to the controller class itself using
If you don't want the original method to be triggered, tell Magento to not further dispatch the action:
For the sake of completeness: You can also prevent "postdispatch" events in a similar way, but this is usually not necessary (here is an example where it's useful: XML has extra content):
Speaking of which, you can also add an observer for
controller_action_postdispatch_$FRONTNAME_$CONTROLLER_$ACTION
if you want to perform additional actions or modifications of the response after the original action has been executed.