Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get controller method in Observer in magento?

Tags:

magento

I need controller method in Observer

My observer :

public function observer()
{
//need controller action here
}

My Controller:

public function adminAction()
    {
    //my action
    }

My questions

  1. Is this possible to call controller method in observer in magento.
  2. If yes please explain how? if no then is there any way to hit controller action through observer?
like image 376
Deepak Mankotia Avatar asked Mar 18 '23 08:03

Deepak Mankotia


2 Answers

You can instantiate a controller anywhere with

$controller = Mage::getControllerInstance(
    'The_Controller_Class',
    Mage::app()->getRequest(),
    Mage::app()->getResponse());

To tell if this is the best way, I would need to know more about your use case, but it probably isn't. If you want to show a different page without redirecting, have a look at 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 from within a controller. But you can do the same from anywhere else. What is happening here:

  1. The original request (available via Mage::app()->getRequest()) is backed up: $request->initForward()
  2. The request object then gets modified with a different controller action and parameters.
  3. The "dispatched" flag of the request is set to false. This way, after the current controller action is finished, the front controller will dispatch the request again with the now changed parameters.

If your observer is attached to an event that takes place before dispatching, it is sufficient to change the request parameters.

like image 85
Fabian Schmengler Avatar answered Apr 08 '23 05:04

Fabian Schmengler


Yes, you can listen on dynamic events:

controller_action_predispatch_' . $this->getFullActionName()
or
controller_action_postdispatch_' . $this->getFullActionName()

You can find the dispatch of these events in app/code/core/Mage/Core/Controller/Varien/Action.php

The method $this->getFullActionName() returns a string formed by routeName_controllerName_actionName so, assuming that your routeName is myadminroute, your controllerName is mycontroller and your action is admin (like your code) you can listen on the events:

controller_action_predispatch_myadminroute_mycontroller_admin
and
controller_action_postdispatch_myadminroute_mycontroller_admin

If you are in the admin area you can listen on:

controller_action_predispatch_adminhtml_myadminroute_mycontroller_admin
and
controller_action_postdispatch_adminhtml_myadminroute_mycontroller_admin

in your observer class you can retrieve the action controller by doing:

$observer->getControllerAction()

Example:

Supposing you are in 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
    }
}
like image 25
Cristiano Casciotti Avatar answered Apr 08 '23 05:04

Cristiano Casciotti