Я хочу удалить вид магазина программно . Глядя на Mage_Adminhtml_System_StoreController::deleteStorePostAction()
это, это довольно легко (немного сокращенный код):
$model = Mage::getModel('core/store')->load($id);
if ($model->getId() && $model->isCanDelete()) {
$model->delete();
Mage::dispatchEvent('store_delete', array('store' => $model));
}
Я хочу поместить этот код в скрипт обновления данных, чтобы удаление выполнялось автоматически.
Проблема заключается в том, что при выполнении сценариев обновления в data/
Magento вызывается только наблюдатель событий, настроенный в этой global
области (см. Обновления структуры Magento и Обновления данных ). Определенные наблюдатели, такие как enterprise_cms
и enterprise_search
для события store_delete_after
, определены в adminhtml
области, поэтому они не будут выполнены. Удаление представления магазина не будет обрабатываться как удаление, выполненное в серверной части.
Как вы справляетесь с такими операциями? Загружать дополнительные области событий самостоятельно в сценарии обновления (я боюсь этого)? Не выполняйте такие модификации данных в сценарии обновления, а кладите свои магические надписи в священное и скрытое место и выполняйте их вручную?
источник
Ответы:
Вскоре после того, как я написал это Матиасу, я начал молчать по радио. Я надеюсь, что вы чувствовали неизвестность, поскольку вы ждали этот ответ в течение пары недель.
То, что я имею в виду под «я делаю это в очереди», является прямым ответом на:
Метод очереди:
Когда я знаю, что есть определенные события, которые не будут запускаться в правильном контексте (в основном для EE, но могут применяться в других контекстах), я обычно выталкиваю удаление в очередь, чтобы оно выполнялось в контексте, который ему необходим ,
Другими словами, создайте таблицу очередей (или очередь / тему в RabbitMQ и т. Д.), Которая будет содержать подробную информацию о транзакции и обработчиках событий, которые она должна прослушивать. Это может быть настолько элегантно или просто, насколько вы хотите. Вот основной
А затем обработайте очередь позже в CRON, где у вас теперь есть контроль над тем, какое хранилище «работает» (иначе вы просто запускаете его, как будто это администратор, хранилище 0):
Очевидно, что если вы начинаете фантазировать, вы заключаете сделку / ловите и заключаете сделку. Я думаю, ты понял суть.
Вероятно, это единственный способ контролировать контекст, в котором происходит событие.
Метод тандемного события:
Вы можете вручную запустить метод «adminhtml» - Алан довольно неплохо объясняет, что бы вы сделали, чтобы повлиять на это , но, по сути, он такой же, как этот:
Административная версия сохранения клиента вызывает обычное сохранение модели и затем отправляет событие adminhtml. Вы можете сделать обратное в наблюдателе самостоятельно, если пожелаете.
источник
Черт возьми, я люблю кое-что, но я должен не согласиться со сложностью / хрупкостью переноса параметров задачи и области ( adminhtml | crontab | frontend | global | install ) в очередь, особенно если эта очередь будет выполняться Magento контекст. Если есть смешанные контексты, которые требуют обработки, тогда решение очереди - это переопределение текущей «проблемы»!
Я думаю, что подход к очереди является хрупким. Мой аргумент заключается в том, что преждевременная загрузка областей событий вообще не является проблемой. Чтобы объяснить это, давайте вернемся назад и посмотрим на проблему:
Чтобы понять это, мы должны изучить области событий в контексте выполнения. Матиас, я полагаю, что вы уже знаете это, но для наставления других:
Сценарии настройки данных выполняются
Mage_Core_Model_App::run()
до отправки запроса на Front Controller:К тому времени, когда выполняются сценарии настройки данных, глобальная область событий загружена. Области событий маршрутизации и контекста ( frontend или adminhtml ) загружаются позже в
Mage_Core_Controller_Varien_Action::preDispatch()
результате того, что маршрутизатор соответствует действию контроллера (area
имя задается посредством наследования):Поэтому обычно во время инициализации приложения будут выполняться только те наблюдатели, которые сконфигурированы в глобальной области событий. Если сценарий установки делает что-то вроде
тогда есть только две опасности:
controller_front_init_before
илиcontroller_front_init_routers
№ 1 должно быть легко найти. # 2 - это реальная проблема, и я думаю, что Reflection может решить эту проблему (обратите внимание, что я крайне неопытен в использовании отражения):
Я не проверял это, но он удаляет индекс события adminhtml и соответствующий
Mage_Core_Model_App_Area
объект.источник