Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento: How do you disable or change how a core observer method works

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.

like image 766
dan.codes Avatar asked Sep 28 '10 20:09

dan.codes


2 Answers

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.

like image 177
Alan Storm Avatar answered Nov 03 '22 21:11

Alan Storm


A better method of doing this is to simply re-declare the observer's definition in a config.xml file.

For example, I needed to disable the enterprise_persistent_cart observer which was declared on event controller_action_layout_generate_blocks_after by module Enterprise_Persistent.

The declaration in Enterprise_Persistent's config.xml file is such

<frontend>
    <events>
        <controller_action_layout_generate_blocks_after>
            <observers>
                <enterprise_persistent_cart>
                    <class>enterprise_persistent/observer</class>
                    <method>removeCartLink</method>
                </enterprise_persistent_cart>
            </observers>
       </controller_action_layout_generate_blocks_after>

So I created a module, and in my module's config.xml, I did the following:

<frontend>
    <events>
        <controller_action_layout_generate_blocks_after>
            <observers>
                <enterprise_persistent_cart>
                    <type>disabled</type>
                </enterprise_persistent_cart>
            </observers>
        </controller_action_layout_generate_blocks_after>

I also made my module depend on the Enterprise_Persistent module. This is necessary to make sure my module's config.xml is processed AFTER the Enterprise_Persistent module's config.xml. I did this by doing the following in my module's app/etc/modules My_Module.xml module declaration file

<config>
    <modules>
        <Atlex_AddCartLinkToHeader>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Enterprise_Persistent/>
            </depends>
        </Atlex_AddCartLinkToHeader>
    </modules>
</config>

For each event, there can only be one observer action declared for a given observer name. Therefore, as long as my module's config.xml is processed after the Enterprise_Persistent module's config.xml file, my observer declaration for enterprise_persistent_cart will be the observer action which is excuted.

The <type> disabled </type> node will disable the observer from firing. If you wanted to override the observer to execute your own method, then you would simply replace the <type> node with your observer's <class> and <method> nodes.

This allows you to override/disable observers without overriding core classes. It's more extendable for future developers.

like image 42
Sean Avatar answered Nov 03 '22 22:11

Sean