views:

66

answers:

2

I have been wondering about this for a while. What if Magento has written a core Observer class and performs a functionality that you do not want it to execute, or you want to rewrite it? Is there a way to say, don't use this method in an Observer, just use mine. If I setup a method for my own Observer won't it just do the core functionality first and then whatever I have implement?

For example, Magento wants to save some data to the database in an Observer method, but I don't want it to save that data at all, I want it to save some other data that I have added columns or attributes to the database for.

+4  A: 

Standard caveat about class overrides being the last resort for implementing your own functionality

It's probably possible to fiddle with the loading of the Magento global config to strip out a core Magento Observer, but there's no supported way for doing it.

However, consider how the Core observers are configured.

<adminhtml>
    <events>
        <cms_wysiwyg_config_prepare>
            <observers>
                <widget_observer>
                    <class>widget/observer</class>
                    <method>prepareWidgetsPluginConfig</method>
                </widget_observer>
            </observers>
        </cms_wysiwyg_config_prepare>
    </events>
</adminhtml>

Observers are Magento Model classes. If a Model's been configured with the URI/path based syntax

<class>widget/observer</class>

as opposed to a full PHP class name

<class>Mage_Widget_Model_Observer</class>

you can create an override for the Observer Model class (just as you can for any other Model). If a PHP class name's been used, you're out of luck. (You could place a local file in local/Mage/Widget/Model/Observer.php if you're willing to take on the responsibility of maintenance, but I don't recommend it)

So, to override the above observer, you would

  1. Create a custom module that include an override for the class Mage_Widget_Model_Observer.

  2. In your override class, either redeclare prepareWidgetsPluginConfig to do what you want OR override the specific method. This could include a empty method to completely remove the functionality.

Alan Storm
Thanks a lot Alan, I was thinking that you must be able to rewrite it but couldn't find anyone talking about doing this. This is the one thing I have been stumped about. I did find removeObserverByName($observerName) In Event.php in the lib directory but wasn't sure about how to use it. I like your approache and will try it in the morning and let you know how it works.
dan.codes
+3  A: 

I wanted to add a comment to @Alan's answer because I think he's nailed it, but my comment got too long and not enough formatting! Here goes:

Nice one @Alan, a clever way to fix what appears to be a hole while still respecting the architecture. A couple of thoughts:

  1. if a custom module binds to the same event, the custom Observer would be called later in the Chain of Responsiblity than the core and hence could possibly override the core Observer? This depends on what the core Observer is doing, e.g. setting a redirect value. In the example the OP provided, this will work. When binding to a Model_save_before event, the core Observer will get called, but your Observer can still modify the contents of the model save data before it is written to the database. You can change or unset the values that are affected by the core Observer.

  2. to override the core Observer's model, inserting a <models><widget><rewrite> in the config.xml would be the right approach

  3. this might be one of the few cases where calling parent:: is not required when overriding(!)

HTH, JD

EDIT - more info added in step 1 to answer specifics of OP's question

Jonathan Day
Thanks Jonathon, I really appreciate, like I said in Alans answer this is something that I have been super confused about how to approach and both of you guys have really cleared this up for me and hopefully anyone else struggling with this also, since you can't find it anywhere when searching.
dan.codes