1

So here is the scenario that I need to achieve. I have a custom module. In it's controller, I am setting a cookie when some conditions are met. I need to check the status of this cookie if any other url request is made through an observer (event using is controller_action_predispatch). When some conditions are met, I will delete this cookie and then I don't want to trigger the event any more (or till next time when the cookie sets through my controller.).

An example shown below. My custom controller looks like this

File: app\code\local\Namespace\Module\controllers\CustomController.php

public function someAction()
{
      if (<some_condition_met>) {
          Mage::getModel('core/cookie')->set('cookiename', 'value', 7200);
          $this->activateObserver($eventname, $modulename, $methodname); // I need this. Later for all action it should observer the event that is specified inside `activateObserver()`
      }
}

activateObserver() will starts event triggering. Now onwards, for every action, it should observe to my custom obsever method.

Now my observer method looks like this.

File : app\code\local\Namespace\Module\Model\Observer.php

public function myObserverMethod($observer)
{
        if (<some_condition_met>) {
             Mage::getModel('core/cookie')->delete('cookiename');
             $this->deactivateObserver($eventname, $modulename); //this should deactivate event observation. Now onwards I dont need to observe this event
        }
}

Now here deactivateObserver() deactivate event triggering from my module.

Why I need this ?

This is because, I am observing to controller_action_predispatch. I just want to observe this event during the life time of my cookie. This cookies life time is 2 hours maximum. Since the event that I am observing occurs for every action, it would be definitely a burden and I need to avoid this.

Is it possible in Magento ? Share your thoughts.

6
  • are you want to unset cookie for all action except your controllers action? – Amit Bera Sep 17 '14 at 5:20
  • after setting cookie, I need to use event to validate the cookie, when every other action takes place. Once cookie deleted, I don't want to observe to the event – Rajeev K Tomy Sep 17 '14 at 5:23
  • is $this->deactivateObserver event -oberver or just model? – Amit Bera Sep 17 '14 at 5:41
  • I just showed it as an example. Such method doesn't exist. I need to create that function, most probably inside my model.. – Rajeev K Tomy Sep 17 '14 at 5:42
  • are you want after cookie delete cookie .you donot run Mage::getModel('core/cookie')->delete('cookiename'); again? – Amit Bera Sep 17 '14 at 5:47
3

This is not possible - the event will be fired each time for every module including yours. You can only programmatically deactivate the event observer completely, but this is not what you are after.

So the thing you would normally do is to directly check in your observer method if the cookie is set and if it is not set, return instantly:

public function myObserverMethod($observer)
{
    if (<cookie_not_set>) {
        return;
    }
    // do whatever you need to do
}

I understand your point that you do not want to do it like that, because the event is fired so often. The only solution I see here is that you could potentially use a more specific event which is not fired that often like controller_action_predispatch_cms or controller_action_predispatch_cms_index_index. Have a look at the event dispatching code here in order to find a suitable event.

3
  • you are right... – Amit Bera Sep 17 '14 at 6:15
  • yes I know I can narrow down the scope. I am now using controller_action_postdispatch_customer_account_loginPost. But this limits my module some extent. Why ? suppose a user use another controller action to validate post action, then my method do not going to fire any more. – Rajeev K Tomy Sep 17 '14 at 6:20
  • i am 97% sure that, it is not possible. But there is 3% doubt persists. That is why I raised this question. Thanks to confirm it. You know one thing, you are a genius :) +1 for it – Rajeev K Tomy Sep 17 '14 at 6:21
1

I think this can be another solution if you set your observer as dispatched once it is triggered, and do nothing once it is already dispatched, this is basically regarding unregistering an observer:

public function updateCustomer($observer){
    if (Mage::registry('my_event_was_dispatched') == 1){//do nothing if the event was dispatched
        return $this;
    }
    //your code here
    Mage::register('my_event_was_dispatched', 1);//mark the event as dispatched.
}

Check this reference URL, this may be another alternate.

4
  • Yes. You are right. But I just want to avoid the if checking that is carrying out my observer, after my cookie "died". Means I dont want to trigger it at all. I just asked this question for a curiosity. Glad to here another beautiful alternative solution :) – Rajeev K Tomy Sep 17 '14 at 6:32
  • additionally, I am trying this concept indeed. look comments on amit's answer. I cant get a global variable inside my observer. i am wondering why ? – Rajeev K Tomy Sep 17 '14 at 6:34
  • The way you are doing is right, try passing static value for once, and check – TBI Infotech Sep 17 '14 at 7:11
  • I have tried lot of things. Trying to pass a string, integer. I have checked whether value is setting or not in the controller itself. There i can see the value. But I cant get it in an observer. Seems wierd – Rajeev K Tomy Sep 17 '14 at 7:16
0

It's possible to disable an entire event in your module config:

...
<events>
    <some_event_observer>
        <observers>
            <unique_string>
                <type>disabled</type>
            </unique_string>
        </observers>
    </some_event_observer>
</events>
...

And you can also achieve this on the fly but you wouldn't want to anyway as it would mean that event wouldn't fire at all so any other observers attached to it won't fire either. As far as I know there isn't anything like this to disable just a single observer so if you wanted that, you would probably have to hack around in the config object.

Doesn't strike me as a great idea to be honest and not something I have ever tried to do so I can't really give you any pointers. If you are not happy using an observer which fires every request and you have to use this observer (i.e. you can't do something more controller/action specific) then the best you can do is look for an alternative way to achieve whatever it is your end goal is, there is almost definitely a better solution.

3
  • Ya I am agreeing with you – Rajeev K Tomy Sep 17 '14 at 6:23
  • Hussey. is disabled valid type? – Amit Bera Sep 17 '14 at 6:51
  • I believe so yes, but by all means test and if you find it not to be the case let me know. – Jonathan Hussey Sep 17 '14 at 7:42
0

I am agree with @Simon but
i suggest that you have do this a global flag.for global flag you need to use Mage::registry()

Step1: Create global registry variable when you have goes to someAction set it value to 1;

Step2: when events controller_action_predispatch is trigger and then condition is match for delete and check registry variable exit and it value is 1

Step3: then this registry variable makes to 0;

it just a concept basic

6
  • I have tried it. I used Mage_register('some_name', 'value'); in my controller and then use Mage::registry('some_name'); inside my observer. But it returns null. I dont know why. I am digging more now – Rajeev K Tomy Sep 17 '14 at 6:26
  • ok.let me check – Amit Bera Sep 17 '14 at 6:30
  • did you check it? its not working here. – Rajeev K Tomy Sep 17 '14 at 6:56
  • i will check just give me time – Amit Bera Sep 17 '14 at 6:57
  • registry variable not work.just used session variable instead of it.check this... – Amit Bera Sep 17 '14 at 8:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.