9

I am attempting to inject functionality into the catalog_model_product_duplicate event. Part of this module will be to ensure that the stock status of the duplicated product is also duplicated; currently it is not.

I see that CatalogInventory observes this event and sets up some standard stock information. Can I be guaranteed that core events are resolved before my locals? Is there any order of operations here that I can rely upon?

11

The order that events are dispatched in is dependent on the order in which the modules are loaded. Since you are needing to be sure that the CatalogInventory module's observers fire before yours does, what you need to do is simply configure your module to depend on the Mage_CatalogInventory module. You can do this by adding a depends node to the code in your app/etc/modules/My_Module.xml file:

<config>
    <modules>
        <My_Module>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_CatalogInventory />
            </depends>
        </My_Module>
    </modules>
</config>

The depends node in the above XML is the crucial piece of configuration here, as it forces the Magento core module to load before yours does.

7

The order in which events are dispatched cannot be easily guaranteed. They're dependent on the order in which modules are loaded. Typically all core event observers will be called prior to community and local code pool observers.

There is a method to force magento observers to fire after a custom one by "faking" a dependency of a core module to a local or community one. Have a look to Lee's answer here: Make a custom observer fire before an existing Magento observer.

/app/etc/modules/Groupname_Page.xml

<config>
    <modules>
        <Groupname_Page>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <!-- Your dependencies go here -->
            </depends>
        </Groupname_Page>
        <Enterprise_PageCache>
            <depends>
                <Groupname_Page />
            </depends>
        </Enterprise_PageCache>
    </modules>
</config>

I personally don't like that approach as I don't know what consequences forcing that dependency would have.

For your use case, it sounds that you should do some sort of detecting for data/state to know whether it was fired or not. Checking a data/state on a model would be preferable than trying to force an event order.

  • In my case, however, I have nothing to do if the stock item doesn't exist yet. Any thoughts on a later event that I could sniff to see if it was a result of the duplicate method? – philwinkle Jan 30 '13 at 20:06
4

A general answer

Observers are executed by area first, then by module loading order

That means, all observers registered in <global> are executed before all observers registered in <frontend> or <adminhtml>.

Within an area, observers are executed in the order they appear in the merged config XML tree, which means technically in the order the modules have been loaded.

Module loading order is determined as follows:

  1. A dependency graph is built from <depends> definitions in app/etc/modules/*.xml. If X depends on Y, Y is loaded before X.

  2. After ordering by dependency, core modules have precedence over community and local modules

  3. Everything else is loaded alphabetically. Note that the file name in app/etc/modules is used for comparison, not the actual module name.

So you have two options to influence module loading order:

  1. depend on another module to have your observers executed after it (or make the other module depend on yours to have them executed before)
  2. Rename the module definition file. You don't need to rename the module itself because the filename does not matter for anything else than loading order.

("3. add your module to the core code pool" does not count)

See also:

1

Just a suggestion, observe both catalog_model_product_duplicate and catalog_model_product_save_after with singleton observer. In catalog_model_product_duplicate set inventory data as observer data, and in catalog_model_product_save_after use that data to populate inventory for duplicated product.

  • So you're suggesting saving a property to the object that was given to me in the event, then testing that on catalog_model_product_save_after... that could work. The only pitfall would be persisting the property without calling save()... any thoughts there? – philwinkle Jan 30 '13 at 21:57
  • You will be saving inventory model, not the product, so you shouldn't be caught in a loop. – Petar Dzhambazov Jan 30 '13 at 23:47

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.