Quiero eliminar una vista de la tienda mediante programación . Mirando Mage_Adminhtml_System_StoreController::deleteStorePostAction()
, esto es bastante fácil (código acortado un poco):
$model = Mage::getModel('core/store')->load($id);
if ($model->getId() && $model->isCanDelete()) {
$model->delete();
Mage::dispatchEvent('store_delete', array('store' => $model));
}
Quiero poner este código en un script de actualización de datos para que la eliminación se ejecute automáticamente.
El problema es que al ejecutar los scripts de actualización en data/
Magento solo se llama a los observadores de eventos configurados en el global
área (ver Actualizaciones de estructura de Magento vs. Actualizaciones de datos ). Ciertos observadores como enterprise_cms
y enterprise_search
para el evento store_delete_after
se definen en el adminhtml
área para que no se ejecuten. La eliminación de la vista de la tienda no se manejará como una eliminación ejecutada en el back-end.
¿Cómo manejas operaciones como esta? ¿Cargar áreas de eventos adicionales en los scripts de actualización (me temo que eso)? ¿No haces modificaciones de datos como esa en la secuencia de comandos de actualización sino que colocas tus secuencias de comandos mágicas en un lugar sagrado escondido y las ejecutas manualmente?
fuente
Respuestas:
Entonces, poco después de twittear esto a Matthias, entré en silencio por radio. Espero que hayas sentido el suspenso mientras esperabas esta respuesta por un par de semanas.
Lo que quiero decir con "hago esto en una cola" es una respuesta directa a:
Método de cola:
Cuando sé que hay ciertos eventos que no se dispararán en el contexto correcto (principalmente para EE, pero pueden aplicarse en otros contextos), generalmente empujo la eliminación a una cola para que se ejecute en el contexto que necesita. .
En otras palabras, cree una tabla de cola (o cola / tema en RabbitMQ, etc.) que contendría detalles de la transacción y los ganchos de eventos que debería estar escuchando. Esto puede ser tan elegante o tan simple como quieras que sea. Aquí hay un básico
Y luego trabaje la cola más tarde en un CRON, donde ahora tiene control sobre qué tienda está "ejecutándose" (es decir, solo lo está ejecutando como si fuera el administrador, tienda 0):
Obviamente, si te apetece, envuelves un intento / captura y envuelves una transacción. Creo que entiendes la esencia.
Esta es posiblemente la única forma de controlar el contexto en el que se desencadena el evento.
Método de evento en tándem:
Puede activar el método "adminhtml" usted mismo manualmente: Alan da una explicación bastante decente de lo que haría para afectar eso , pero esencialmente es lo mismo que esto:
La versión de administración del cliente guardar llama al modelo normal guardar y luego envía el evento adminhtml. Podrías hacer lo contrario de esto en un observador si lo deseas.
fuente
Maldita sea, me encanta un poco de philwinkle, pero tengo que estar en desacuerdo con la complejidad / fragilidad de transportar los parámetros de la tarea y el área ( adminhtml | crontab | frontend | global | install ) a una cola, especialmente si esa cola se va a ejecutar Un contexto de Magento. Si hay contextos mixtos que necesitan ser manejados, entonces la solución de la cola es una reimplementación del "problema" actual.
Creo que el enfoque de la cola es frágil. Mi argumento es que cargar áreas de eventos prematuramente no es realmente un problema en absoluto. Para explicar esto, retrocedamos y veamos el problema:
Para comprender esto, debemos examinar las áreas de eventos en el contexto de ejecución. Matthias, imagino que ya lo sabes, pero para la edificación de otros:
Los scripts de configuración de datos se ejecutan
Mage_Core_Model_App::run()
antes de enviar la solicitud al controlador frontal:Para cuando se ejecutan los scripts de configuración de datos , se carga el área de evento global . Las áreas de eventos contextuales de enrutamiento ( frontend o adminhtml ) se cargan más adelante
Mage_Core_Controller_Varien_Action::preDispatch()
como resultado de que el enrutador coincida con una acción del controlador (elarea
nombre se establece por herencia):Por lo tanto, normalmente durante la inicialización de la aplicación, solo se ejecutarán los observadores configurados en el área de evento global . Si el script de configuración hace algo como
entonces solo hay dos peligros:
controller_front_init_before
ocontroller_front_init_routers
# 1 debería ser fácil de conseguir. # 2 es la verdadera preocupación, y creo que Reflection puede resolver el problema (tenga en cuenta que lamentablemente no tengo experiencia con el uso de la reflexión):
No he probado esto, pero elimina el índice de eventos adminhtml y el
Mage_Core_Model_App_Area
objeto correspondiente .fuente