Więc krótko po tym, jak napisałem to na Twitterze do Macieja, przeszedłem w ciszy radiowej. Mam nadzieję, że poczułeś napięcie, czekając na odpowiedź od kilku tygodni.
To, co rozumiem przez „robię to w kolejce”, jest bezpośrednią odpowiedzią na:
Niektóre obserwatory, takie jak enterprise_cms i enterprise_search dla zdarzenia store_delete_after, są zdefiniowane w obszarze adminhtml, więc nie zostaną wykonane. Usunięcie widoku sklepu nie będzie traktowane jak usunięcie wykonane w wewnętrznej bazie danych.
Metoda kolejki:
Kiedy wiem, że istnieją pewne zdarzenia, które nie będą uruchamiane we właściwym kontekście (głównie dla EE, ale mogą mieć zastosowanie w innych kontekstach), zwykle usuwam usunięcie z kolejki, aby działało w kontekście, w którym musi .
Innymi słowy, utwórz tabelę kolejek (lub kolejkę / temat w RabbitMQ itp.), Która zawierałaby szczegóły transakcji i haczyki zdarzeń, których powinna nasłuchiwać. Może to być tak eleganckie lub tak proste, jak chcesz. Oto podstawowa
$queue = Mage::getModel('yourcompany/queue_job')
->setJobType('delete')
->setEntityType('core/store')
->setEntityId(12)
->setDispatchEvent('store_delete')
->setDispatchEventDataKey('store')
->save();
A potem pracuj w kolejce później w CRON, gdzie masz teraz kontrolę nad tym, który sklep „działa” (czyli po prostu uruchamiasz go tak, jakby to był administrator, sklep 0):
foreach(Mage::getModel('yourcompany/queue_job')->getCollection() as $job){
if($job->getJobType()=='delete'){
$model = Mage::getModel($this->getEntityType())->load($this->getEntityId());
if ($model->getId() && $model->isCanDelete()) {
$model->delete();
Mage::dispatchEvent($job->getDispatchEvent(), array($job->setDispatchEventDataKey() => $model));
}
}
}
Oczywiście, jeśli masz ochotę, zawijaj try / catch i zawijaj transakcję. Myślę, że rozumiesz.
Jest to realnie jedyny sposób kontrolowania kontekstu, w którym wydarzenie się uruchamia.
Metoda zdarzenia tandemowego:
Możesz samodzielnie uruchomić metodę „adminhtml” - Alan daje całkiem przyzwoite wyjaśnienie, co byś zrobił, aby na to wpłynąć , ale zasadniczo jest to to samo:
#File: app/code/core/Mage/Adminhtml/controllers/CustomerController.php
public function saveAction()
{
//...
$customer->save();
//...
Mage::dispatchEvent('adminhtml_customer_prepare_save', array(
'customer' => $customer,
'request' => $this->getRequest()
));
//..
}
Administracyjna wersja składowania klienta wywołuje zwykłe zapisywanie modelu, a następnie wywołuje zdarzenie adminhtml. Możesz zrobić to odwrotnie u obserwatora, jeśli chcesz.