How to get controller method in Observer in magento?
I need a controller method in Observer
My observer:
public function observer()
{
//need controller action here
}
My controller:
public function adminAction()
{
//my action
}
My questions
- Is it possible to call a controller method in an observer in magento.
- If so, please explain how? if not, is there a way to hit the controller action through the observer?
source to share
Yes, you can listen to dynamic events:
controller_action_predispatch_' . $this->getFullActionName()
or controller_action_postdispatch_' . $this->getFullActionName()
You can find sending these events at app/code/core/Mage/Core/Controller/Varien/Action.php
The method $this->getFullActionName()
returns a string formed routeName_controllerName_actionName
, so assuming your route name myadminroute
, your controller name, mycontroller
and your action admin
(like your code), you can listen for events:
controller_action_predispatch_myadminroute_mycontroller_admin
and controller_action_postdispatch_myadminroute_mycontroller_admin
If you are in the admin area, you can listen to:
controller_action_predispatch_adminhtml_myadminroute_mycontroller_admin
and controller_action_postdispatch_adminhtml_myadminroute_mycontroller_admin
in your observer class, you can get the action controller by doing the following:
$observer->getControllerAction()
Example:
Let's assume you are in the admin area:
<config>
...
<models>
<my_model_prefix>
<class>MyNamespace_MyModule_Model</class>
</my_model_prefix>
</models>
...
<events>
<controller_action_predispatch_adminhtml_myadminroute_mycontroller_admin>
<observers>
<my_event_unique_tag>
<type>singleton</type>
<class>my_model_prefix/observer</class>
<method>myObserverMethod</method>
</my_event_unique_tag>
</observers>
</controller_action_predispatch_adminhtml_myadminroute_mycontroller_admin>
</events>
...
</config>
in Model/Observer.php
:
class MyNamespace_MyModule_Model_Observer
{
public function myObserverMethod($observer)
{
$controller = $observer->getControllerAction();
// do some stuff
}
}
source to share
You can instantiate the controller anywhere with
$controller = Mage::getControllerInstance(
'The_Controller_Class',
Mage::app()->getRequest(),
Mage::app()->getResponse());
To say that this is the best way I will need to know more about your use case, but it probably isn't. If you want to show another page without redirecting, take a look Mage_Core_Controller_Varien_Action::_forward()
:
/**
* Throw control to different action (control and module if was specified).
*
* @param string $action
* @param string|null $controller
* @param string|null $module
* @param array|null $params
*/
protected function _forward($action, $controller = null, $module = null, array $params = null)
{
$request = $this->getRequest();
$request->initForward();
if (isset($params)) {
$request->setParams($params);
}
if (isset($controller)) {
$request->setControllerName($controller);
// Module should only be reset if controller has been specified
if (isset($module)) {
$request->setModuleName($module);
}
}
$request->setActionName($action)
->setDispatched(false);
}
Unfortunately this is protected, so it can only be used inside a controller. But you can do the same from somewhere else. What's going on here:
- Original request (accessible via
Mage::app()->getRequest()
) backup:$request->initForward()
- Then the request object is modified with another action and controller parameters.
- The "sent" request flag is false. Thus, after the current controller action is finished, the front controller will again send a request with the changed parameters.
If your observer is bound to an event that occurs before dispatch, it is enough to change the request parameters.
source to share