Saya ingin menghapus tampilan toko secara terprogram . Melihat Mage_Adminhtml_System_StoreController::deleteStorePostAction()
, ini cukup mudah (kode singkat):
$model = Mage::getModel('core/store')->load($id);
if ($model->getId() && $model->isCanDelete()) {
$model->delete();
Mage::dispatchEvent('store_delete', array('store' => $model));
}
Saya ingin memasukkan kode ini ke dalam skrip pemutakhiran data sehingga penghapusan akan dilakukan secara otomatis.
Masalahnya adalah saat menjalankan skrip peningkatan di data/
Magento hanya memanggil pengamat acara yang dikonfigurasi di global
area tersebut (lihat Pembaruan Struktur Magento vs. Pembaruan Data ). Pengamat tertentu menyukai enterprise_cms
dan enterprise_search
untuk acara store_delete_after
tersebut ditentukan di adminhtml
daerah sehingga mereka tidak akan dieksekusi. Penghapusan tampilan toko tidak akan ditangani seperti penghapusan yang dilakukan di backend.
Bagaimana Anda menangani operasi seperti ini? Muat area acara tambahan sendiri di skrip pemutakhiran (saya takut itu)? Jangan melakukan modifikasi data seperti itu di skrip pemutakhiran tetapi letakkan skrip ajaib Anda di tempat tersembunyi yang suci dan jalankan secara manual?
sumber
Jawaban:
Maka tak lama setelah saya tweet ini ke Matthias saya pergi di radio diam. Saya harap Anda merasakan ketegangan saat Anda menunggu jawaban ini selama beberapa minggu sekarang.
Yang saya maksud dengan "Saya melakukan ini dalam antrian" adalah respons langsung terhadap:
Metode Antrian:
Ketika saya tahu bahwa ada peristiwa tertentu yang tidak akan diaktifkan dalam konteks yang benar (sebagian besar untuk EE, tetapi mungkin berlaku dalam konteks lain) saya biasanya mendorong penghapusan ke antrian sehingga akan berjalan dalam konteks yang diperlukan untuk .
Dengan kata lain, buat tabel antrian (atau antrian / topik di RabbitMQ, dll.) Yang akan berisi perincian transaksi dan kait acara yang harus didengarkan. Ini bisa menjadi elegan atau sesederhana yang Anda inginkan. Ini dasar
Dan kemudian kerjakan antriannya nanti dalam CRON, di mana Anda sekarang memiliki kendali atas toko mana yang "berjalan" (alias Anda hanya menjalankannya seolah-olah itu admin, store 0):
Jelas jika Anda mulai menyukai Anda membungkus mencoba / menangkap dan membungkus transaksi. Saya pikir Anda mendapatkan intinya.
Ini mungkin satu-satunya cara untuk mengendalikan konteks di mana peristiwa tersebut terjadi.
Metode acara Tandem:
Anda dapat menjalankan sendiri metode "adminhtml" secara manual - Alan memberikan penjelasan yang cukup baik tentang apa yang akan Anda lakukan untuk memengaruhi itu , tetapi pada dasarnya sama dengan ini:
Versi admin pelanggan save memanggil model biasa simpan dan mengirim acara adminhtml sesudahnya. Anda dapat melakukan kebalikan dari ini dalam diri seorang pengamat jika Anda menginginkannya.
sumber
Sialan, saya suka saya beberapa filwinkle, tapi saya harus tidak setuju dengan kompleksitas / kerapuhan mengangkut parameter tugas dan area ( adminhtml | crontab | frontend | global | install ) ke antrian, terutama jika antrian itu akan mengeksekusi konteks Magento. Jika ada konteks campuran yang perlu penanganan maka solusi antrian adalah implementasi ulang dari "masalah" saat ini!
Saya pikir pendekatan antrian rapuh. Argumen saya adalah bahwa memuat area acara secara prematur bukan masalah sama sekali. Untuk menjelaskan ini, mari kita kembali dan melihat masalahnya:
Untuk memahami ini kita harus memeriksa area acara dalam konteks eksekusi. Matthias, saya membayangkan Anda sudah mengetahui hal ini, tetapi untuk peneguhan orang lain:
Skrip pengaturan data dieksekusi
Mage_Core_Model_App::run()
sebelum mengirim permintaan ke Front Controller:Pada saat skrip pengaturan data mengeksekusi area acara global dimuat. Area acara perutean-kontekstual ( frontend atau adminhtml ) dimuat di kemudian hari
Mage_Core_Controller_Varien_Action::preDispatch()
sebagai hasil dari pencocokan router dengan tindakan pengontrol (area
namanya diatur melalui pewarisan):Jadi biasanya selama inisialisasi aplikasi hanya pengamat yang dikonfigurasi di bawah area acara global yang akan dieksekusi. Jika skrip pengaturan melakukan sesuatu seperti
maka hanya ada dua bahaya:
controller_front_init_before
ataucontroller_front_init_routers
# 1 seharusnya mudah dipahami. # 2 adalah masalah nyata, dan saya pikir Refleksi dapat menyelesaikan masalah (perhatikan bahwa saya tidak berpengalaman menggunakan refleksi):
Saya belum menguji ini, tetapi itu menghapus indeks peristiwa adminhtml dan
Mage_Core_Model_App_Area
objek yang sesuai .sumber