Eventos do Observador Magento - ordem das operações

9

Estou tentando injetar funcionalidade no catalog_model_product_duplicateevento. Parte deste módulo será garantir que o status do estoque do produto duplicado também seja duplicado; atualmente não é.

Vejo que CatalogInventoryobserva esse evento e configura algumas informações padrão sobre ações. Posso garantir que os principais eventos sejam resolvidos antes dos meus locais? Existe alguma ordem de operações aqui em que eu possa confiar?

philwinkle
fonte

Respostas:

11

A ordem em que os eventos são despachados depende da ordem em que os módulos são carregados. Como você precisa ter certeza de que os CatalogInventoryobservadores do módulo disparam antes do seu, o que você precisa fazer é simplesmente configurar o módulo para depender do Mage_CatalogInventorymódulo. Você pode fazer isso adicionando um nó depende ao código do seu app/etc/modules/My_Module.xmlarquivo:

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

O dependsnó no XML acima é a parte crucial da configuração aqui, pois força o carregamento do módulo principal do Magento antes do seu.

davidalger
fonte
7

A ordem na qual os eventos são despachados não pode ser facilmente garantida. Eles dependem da ordem em que os módulos são carregados. Normalmente, todos os observadores de eventos principais serão chamados antes dos observadores da comunidade e do conjunto de códigos locais.

Existe um método para forçar os observadores do magento a disparar atrás de um personalizado, "fingindo" uma dependência de um módulo principal para um local ou comunitário. Veja a resposta de Lee aqui: Faça um observador personalizado disparar diante de um observador existente do Magento .

/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>

Pessoalmente, não gosto dessa abordagem, pois não sei quais consequências forçariam essa dependência.

Para o seu caso de uso, parece que você deve fazer algum tipo de detecção de dados / estado para saber se foi acionado ou não. A verificação de um dado / estado em um modelo seria preferível a tentar forçar uma ordem de evento.

beeplogic
fonte
No meu caso, no entanto, não tenho nada a fazer se o item de estoque ainda não existir. Alguma idéia de um evento posterior que eu pudesse cheirar para ver se era resultado do método duplicado?
philwinkle
5

Uma resposta geral

Os observadores são executados primeiro pela área e depois pela ordem de carregamento do módulo

Isso significa que todos os observadores registrados <global>são executados antes de todos os observadores registrados em <frontend>ou <adminhtml>.

Dentro de uma área, os observadores são executados na ordem em que aparecem na árvore XML de configuração mesclada, o que significa tecnicamente na ordem em que os módulos foram carregados.

A ordem de carregamento do módulo é determinada da seguinte forma:

  1. Um gráfico de dependência é construído a partir de <depends>definições em app/etc/modules/*.xml. Se X depende de Y, Y é carregado antes de X.

  2. Após o pedido por dependência, os módulos principais têm precedência sobre os módulos comunitário e local

  3. Todo o resto é carregado em ordem alfabética. Observe que o nome do arquivo app/etc/modulesé usado para comparação, não o nome real do módulo.

Então você tem duas opções para influenciar a ordem de carregamento do módulo:

  1. dependa de outro módulo para que seus observadores sejam executados depois dele (ou faça com que o outro módulo dependa do seu para executá-los antes)
  2. Renomeie o arquivo de definição do módulo. Você não precisa renomear o módulo em si, porque o nome do arquivo não importa para nada além de carregar a ordem.

("3. adicione seu módulo ao pool de códigos principal" não conta)

Veja também:

Fabian Schmengler
fonte
1

Apenas uma sugestão, observe ambos catalog_model_product_duplicatee catalog_model_product_save_aftercom observador singleton. Em catalog_model_product_duplicatedefinir dados de inventário como dados de observador e em catalog_model_product_save_afteruso esses dados para preencher o inventário de produtos duplicados.

Petar Dzhambazov
fonte
Então você está sugerindo salvar uma propriedade no objeto que me foi dado no evento e testá-la em catalog_model_product_save_after... isso poderia funcionar. A única armadilha seria persistir na propriedade sem chamar save()... alguma opinião aí?
philwinkle
Você salvará o modelo de inventário, não o produto, para não ser pego em um loop.
Petar Dzhambazov