Magento overriding an overridden controller? - magento

How can I override a controller which has been overridden in the community codepool? In my case its the Mage_Contacts_IndexController. The controller that overrides this does some stuff in the postAction function and then calls the parent, which is Mage_Contacts_IndexController. My override of Mage_Contacts_IndexController does not work because of that.
Do I have to override the overriding controller in this case?
Thanks!

Usually when you override an already overridden controller, your controller will get executed first only if your module is alphabetically ahead of the module that has already overridden it. For instance if your module name starts with letter "A" and previous module starts with letter "B", in this case yours will be executed first. This is because when magento finds 2 or more modules overriding same class it will go with the one which was fetched first in alphabetical order. You can try that way.
Also check this: overriding a magento block in multiple modules (and how to ignore the other ones)
Hope this helps!!

Codepool canonot create issue in rewrite ,there may be any issues in your module.You need to check this.
Please check this link here you have find you to rewrite controllers class

Related

Joomla - How to override component controller?

I want to override a controller inside a component
ie;
File path : components/com_test/controllers/test.php
how to override test.php ?
As Pritesh mentioned, you can't*.
I can see a couple of ways to achieve the result:
You can create a new controller which extends your test.php controller, and invoke that instead; in order to achieve this, the controller must never use JPATH_COMPONENT and you'll have to override the view as well to point to the right component.
Add a special task to your view, and intercept it with a system plugin in OnAfterRoute(). You won't be touching the original controller, but your plugin will fire before the original controller, so it can take action, manipulate input and output, and eventually avoid invoking the original controller altogether.
--
if editing the original controller could seem like an option, please disregard it: the original component will be updated from time to time and you'd be entering a maintenance nightmare.
Very often I have to achieve just this result. And 90% of the time I achieve this in a system plugin. In case of improvements, I contribute the code back to the original developer, who usually integrates the features in their next release. Don't forget to let the original developers know, you'll help improve their products and save yourself time.
Actually you can override quite a large part of the core, by loading the class before Joomla does; this limits to non-core classes but it is feasible. That's what I was referring to in n.2
we can not override the controller and model in joomla we will override only views of the component.

Mage_Payment_Model_Method_Abstract class override

As title suggest i want to override Mage_Payment_Model_Method_Abstract class , I know that it is abstract class. and we can easily override abstract class using local directory like app\code\local\Mage\Payment\Model\Method\Abstract.php. But i want to know is there any other option for me ? Because this option is not safe with different magento version.
Any help will be appreciated.
Thank you
'Override' is a method where you copy a class from the Magento core into the local code. For ex:
app/code/core/Mage/Rule/Model/Abstract.php
to
app/code/local/Mage/Rule/Model/Abstract.php
An override is where you tell Magento to "Use this class file instead of the other class file". Similar, but different from a rewrite. Rewrites are considered better practice because they're less likely to cause problems with upgrades and extension compatibility.
An abstract class is never instantiated, it can never be rewritten.
If you override, you need to take care of future upgrades. You can't rewrite an abstract class. The rewrite system works because Magento uses a factory pattern to instantiate model, blocks, and helpers.
The other alternative is to use a traditional class override. For ex: Copy
app/code/core/Mage/Rule/Model/Abstract.php
to
app/code/local/Mage/Rule/Model/Abstract.php
Also somewhere on the blog I read this (not in favor though) For ex: Copy
Mage_Shipping_Model_Carrier_Abstract
from
app/code/core/Mage/Shipping/Model/Carrier
to
app/code/local/Mage/Shipping/Model/Carrier
Do NOT change the class name, just change or add the methods as you need.
This is a trick. Magento loads a class from several locations, and app/code/local comes before app/code/core
Good luck!!!

Can I override Magento Varien classes?

I know how to override Mage classes (any class within app/code/core)
My question is how to override Varien classes? (classes within lib/Varien)
If I want to override Mage_Adminhtml_Block_Page_Menu
I create a class MyCompany_Adminhtml_Block_Page_Menu under app/code/local/MyCompany/Adminhtml/Block/Page/Menu.php
I name it like:
class MyCompany_Adminhtml_Block_Page_Menu extends Mage_Adminhtml_Block_Page_Menu
Now Magento uses my class MyCompany_Adminhtml_Block_Page_Menu instead of Mage_Adminhtml_Block_Page_Menu
My question is: where should I put the new class, and how to name it, to override, for example Varien_Date (lib/Varien/Date.php)
Thanks
If you must, copy the file and path to the local codepool and make the necessary changes. There is no configuration mapping to change the class name.
Explanation: see the bootstrapping in app/Mage.php. There is a load order set for the codepools and libraries in the following order:
app/code/local/
app/code/community/
app/code/core/
lib/
Typically, Varien_Autoload is responsible for mapping classnames such as Varien_Data_Collection_Db, Mage_Core_Model_Abstract, or Zend_Db_Select to relative filenames (Varien/Data/Collection/Db.php, Mage/Core/Model/Abstract.php, and Zend/Db/Select.php respectively). These file locations are then passed to include(), which internally uses the load order set in the bootstrap. Therefore, if the file Varien/Data/Collection/Db.php is present under one of the "earlier" locations, that version of the class definition will be used.
These type of modifications may be justified, but they should be well-considered and documented, as the entire definition will be owned by you and any upgrades will need to be merged in the future. It would be good to know what you would like to change, as someone else may have a slightly less invasive option.

How do i override Mage_Core_Controller_Request_Http

I have made some changes to Mage_Core_Controller_Request_Http but in the file distributed by with magento. This is not the best way, i know, but i have not been able to work out how to override a file in the Controller directory. I can find out how to override files in the controllers directory.
Can anyone tell me how i can override Mage_Core_Controller_Request_Http in my own extension.
thanks
If you don't want to revert to the include path hack, you can also use reflection to set your own request class on the Mage_Core_Model_App model. You can use an observer for controller_front_init_before event for that.
I'll assume you are familiar how to create an event observer, soI'll only add the code for the observer method. If you need additional information please ask.
// Observer method
public function controllerFrontInitBefore(Varien_Event_Observer $observer)
{
$app = Mage::app();
$reflection = new ReflectionClass($app);
$property = $reflection->getProperty('_request');
$property->setAccessible(true);
$myRequest = new Your_Module_Controller_Request_Http();
$myRequest->setOrigRequest($app->getRequest()); // if needed
$property->setValue($app, $myRequest);
// Proof of concept:
// Loggs Your_Module_Controller_Request_Http
Mage::log(get_class(Mage::app()->getRequest()));
}
Create the class Your_Module_Controller_Request_Http and extend the original Mage_Core_Controller_Request_Http.
After that event your request object will be used instead of the original.
This enables you to stay as upgrade safe as possible, because you do not have to copy over the full class from the cor code pool.
Edit: Vinai's solution is the better one.
Because this class is instantiated directly, you will have to use the so-called include path hack to override.
The order of precedence for include paths which affect Varien_Autoload's work is set in app/Mage.php. That order is as follows:
app/code/local/
app/code/community/
app/code/core/
lib/
Therefore, if you copy your file to an analogous path under the local or community codepools, your definition of that class will be used.
Since Magento 1.7 you can use the method Mage::app()->setRequest($request) to replace the request object within an observer for the controller_front_init_before event as suggested by Vinai.
WARNING for Magento Enterprise: The Full Page Cache won't work with this method, as it relies on changes to the request object done before controller_front_init_before. You either need to manually copy all properties from the old request to the new - or replace the request class with benmarks solution.

Magento: What is the best way to extend Magento to add a class that is called on every page load

I am looking to create some new functionality to Magento. I am going to be looking to the url and grabbing a parameter. The issue is, this can be on any page. So I can't just extend a Catalog or Checkout Module.
I thought about extending the session classes but I wasn't sure it really fit. Basically I want to grab a parameter from the url and from there add some functionality if it is set or not. I don't think a class will get auto loaded unless it is instantiated somewhere else with a getModel method, am I wrong?
How can you add a module that doesn't have a url path for controller and what not, but doesn't fit extending one of the core modules?
I looked for a generic event but didn't really see one like before_page_load or something
Take a look at the event controller_action_predispatch in app/code/core/Mage/Core/Controller/Varien/Action.php. This event should get called on each dispatch and allow you to grab whatever parameters you need.
The event passes the controller as data, so you can do this:
function yourEvent( $event ) {
$controller = $event->getController();
// your processing here
}
Let me know if that doesn't fit the bill. Hope that helps!
Thanks,
Joe

Resources