Determinar se o cliente é novo em customer_save_after

9

Tenho eventos que desejo executar quando um cliente registra ou salva seus detalhes. Para isso, estou usando dois eventos: customer_register_success e customer_save_after. O problema que estou tendo é que acabo executando a tarefa duas vezes, pois customer_save_after é sempre chamado na mesma execução que customer_register_success.

Tentei detectar se o cliente é novo verificando os dados originais e chamados isObjectNew, mas ambos retornam dados que sugerem que o objeto não é realmente novo. Como posso verificar se o cliente está apenas se registrando no evento customer_save_after antes de definir algo no registro no customer_register_successevento?

Matthew Haworth
fonte

Respostas:

5

Antes de tudo, você pode definir seu observador como singleton para os dois eventos

<global>
    <events>
        <customer_save_after>
            <observers>
                <namespace_module>
                    <type>singleton</type>
                    <class>namespace_module/observer</class>
                    <method>doSomething</method>
                </namespace_module>
            </observers>
        </customer_save_after>
        <customer_register_success>
            <observers>
                <namespace_module>
                    <type>singleton</type>
                    <class>namespace_module/observer</class>
                    <method>doSomething</method>
                </namespace_module>
            </observers>
        </customer_register_success>
    </events>
</global>

Nesse caso, o mesmo objeto observador será usado para ambos os eventos. Assim, você pode criar sinalizador no seu observador e antes de executar algumas ações, verifique-o.

class [Namespace]_[Module]_Model_Observer
{
    protected $canDoSomething = false;

    public function doSomething($observer)
    {
        if (!$this->canDoSomething) {

            //here your code

            //now set flag to true to prevent executing your code twice 
            $this->canDoSomething = true;
        }
    }
}

Agora seu código será executado apenas uma vez.

oleksii.svarychevskyi
fonte
0

A maneira mais fácil de evitar isso é usar um valor do registro. Seu método de observação seria algo como o seguinte

class [Namespace]_[Module]_Model_Observer
{
   public function triggeredObserver($observer)
   {
      if (!empty(Mage::registry('[module]_istriggered')) return $this;

      // here you can perform whatever you want to do with your code

      Mage::register('[module]_istriggered', 1);
   }
}

Na primeira vez em que o método é chamado, ele registra uma chave, o que significa que, na segunda vez em que é acionado, não está mais vazio e o método retornará no início

Sander Mangel
fonte
Sim, eu tinha pensado sobre isso, mas ele se sente :( muito sujo Eu estou surpreso que eu não posso descobrir se um objeto acaba de ser criado em um evento model_save_after.
Matthew Haworth
apenas um beforeevento tem os isObjectNewdados, tanto quanto eu sei, pois os dados ainda não foram salvos. Tanto quanto suja vai, eu acho que não haveria maneiras mais elegantes, mas certamente não é um hack
Sander Mangel
$customer->save(); $this->_dispatchRegisterSuccess($customer);Infelizmente aqui, o cliente é salvo antes do evento registo é acionado, então o método observador não iria funcionar de qualquer maneira :(
Matthew Haworth
0

Outra abordagem é verificar qual controlador e ação acionou o evento.

No observador, você pode obter o nome do módulo, controlador e ação.

$frontName = Mage::app()->getRequest()->getRouteName();
$controllerName = Mage::app()->getRequest()->getControllerName();
$actionName = Mage::app()->getRequest()->getActionName();

$myURI = $frontName . '_'. $controllerName . '_' . $actionName;

E depois verifique no seu método quem está despachando o evento.

Em uma instalação de estoque do magento, ao criar um usuário a partir da área do usuário, o valor de $ myURI seria customer_account_createpost.

Isaias
fonte