Magento gagal saat mencoba menyimpan produk di dalam pengamat acara di frontend?

15

Saya memiliki fungsi yang terkait dengan pengamat acara

Salah satu persyaratan adalah bahwa ketika loop melalui data item pesanan, jika atribut produk tertentu kosong itu mengeluarkan permintaan untuk mendapatkan data spesifik melalui model terpisah (berfungsi dengan baik).

kode masalah pada dasarnya bermuara pada ini

foreach ($order->getAllItems() as $key => $item) {
    /** @var Tantor_Catalog_Model_Product $productData */
    $productData = $item->getProduct();
    $_item = Mage::getModel('catalog/product')->load($productData->getId());
    $_item->setNetsuiteItemIid('foo');
    $_item->save();
}

Namun Magento melempar pengecualian

2014-03-05T21:14:14+00:00 ERR (3):
exception 'Exception' with message 'Warning: Invalid argument supplied for foreach()  in /var/www/html/app/code/core/Mage/Eav/Model/Entity/Abstract.php on line 1180' in /var/www/html/app/code/core/Mage/Core/functions.php:245
Stack trace:
#0 /var/www/html/app/code/core/Mage/Eav/Model/Entity/Abstract.php(1180): mageCoreErrorHandler(2, 'Invalid argumen...', '/var/www/html/a...', 1180, Array)
#1 /var/www/html/app/code/core/Mage/Eav/Model/Entity/Abstract.php(1123): Mage_Eav_Model_Entity_Abstract->_collectSaveData(Object(Tantor_Catalog_Model_Product))
#2 /var/www/html/app/code/core/Mage/Core/Model/Abstract.php(318): Mage_Eav_Model_Entity_Abstract->save(Object(Tantor_Catalog_Model_Product))
#3 /var/www/html/app/code/local/Tantor/Netsuite/Model/Observer.php(218): Mage_Core_Model_Abstract->save()
#4 /var/www/html/app/code/core/Mage/Core/Model/App.php(1338): Tantor_Netsuite_Model_Observer->saveOrder(Object(Varien_Event_Observer))
#5 /var/www/html/app/code/core/Mage/Core/Model/App.php(1317): Mage_Core_Model_App->_callObserverMethod(Object(Tantor_Netsuite_Model_Observer), 'saveOrder', Object(Varien_Event_Observer))
#6 /var/www/html/app/Mage.php(447): Mage_Core_Model_App->dispatchEvent('sales_order_pla...', Array)
#7 /var/www/html/app/code/core/Mage/Sales/Model/Order.php(1096): Mage::dispatchEvent('sales_order_pla...', Array)
#8 [internal function]: Mage_Sales_Model_Order->place()
#9 /var/www/html/app/code/core/Mage/Core/Model/Resource/Transaction.php(105): call_user_func(Array)
#10 /var/www/html/app/code/core/Mage/Core/Model/Resource/Transaction.php(159): Mage_Core_Model_Resource_Transaction->_runCallbacks()
#11 /var/www/html/app/code/core/Mage/Sales/Model/Service/Quote.php(189): Mage_Core_Model_Resource_Transaction->save()
#12 /var/www/html/app/code/core/Mage/Sales/Model/Service/Quote.php(249): Mage_Sales_Model_Service_Quote->submitOrder()
#13 /var/www/html/app/code/core/Mage/Checkout/Model/Type/Onepage.php(774): Mage_Sales_Model_Service_Quote->submitAll()
#14 /var/www/html/app/code/core/Mage/Checkout/controllers/OnepageController.php(511): Mage_Checkout_Model_Type_Onepage->saveOrder()
#15 /var/www/html/app/code/core/Mage/Core/Controller/Varien/Action.php(419): Mage_Checkout_OnepageController->saveOrderAction()
#16 /var/www/html/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(250): Mage_Core_Controller_Varien_Action->dispatch('saveOrder')
#17 /var/www/html/app/code/core/Mage/Core/Controller/Varien/Front.php(176): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
#18 /var/www/html/app/code/core/Mage/Core/Model/App.php(354): Mage_Core_Controller_Varien_Front->dispatch()
#19 /var/www/html/app/Mage.php(683): Mage_Core_Model_App->run(Array)
#20 /var/www/html/index.php(86): Mage::run('', 'store')
#21 {main}

Mengapa saya bisa menggunakan kode identik dalam skrip pihak ke-3 di luar pengamat magento, tetapi ketika saya mencoba menjalankannya di dalam pengamat itu, gagal dengan pesan kesalahan acak itu?

Zxurian
sumber
Kesalahan ini adalah tipikal dari non-array yang diuraikan foreach. Jejak tumpukan menunjukkan Anda suatu peristiwa dikirim dan pengamat rusak. Apakah Anda yakin $order->getAllItems()sedang mengembalikan suatu array()? menggunakan: Zend_Debug::dump($order->getAllItems());. Namun, mungkin pengamat lain dengan kode yang buruk?
ash
masalahnya adalah dengan kode inti Magento, bukan dengan cuplikan saya di atas.
Zxurian

Jawaban:

33

Masalahnya adalah, Anda tidak diperbolehkan menyimpan produk dari frontend.

Ini dilakukan melalui fakta, bahwa ketika Anda memuat produk di frontend, origDataproperti tidak terisi:

public function setOrigData($key=null, $data=null)
{
    if (Mage::app()->getStore()->isAdmin()) {
        return parent::setOrigData($key, $data);
    }

    return $this;
}

Jadi, ketika Anda mencoba menyimpan produk, kesalahan yang Anda uraikan muncul.

Anda dapat memecahkan masalah ini saat Anda mengubah toko saat ini menjadi admin, misalnya dengan kode dari @magboy:

Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

lebih baik menggunakan Mage_Core_Model_App_Emulation

Dan solusi pilihan saya adalah memperluas Mage_Catalog_Model_Productdan mengganti setOrigDatametode

public function setOrigData($key = null, $data = null)
{
    if (is_null($key)) {
        $this->_origData = $this->_data;
    } else {
        $this->_origData[$key] = $data;
    }
    return $this;
}

Saya TIDAK berbicara tentang penulisan ulang di sini! Gunakan hanya model Anda di satu tempat ini untuk mengaktifkan penghematan. Maka Anda memiliki fitur keamanan masih aktif di tempat lain.

Fabian Blechschmidt
sumber
7

Coba tambahkan baris kode ini:

Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

Saya tidak yakin mengapa Anda harus melakukan ini sekarang di versi Magento saat ini. Mungkin orang lain bisa menjelaskan?

tukang sihir
sumber
setelah saya mengatur toko saat ini ke Admin dan menyimpan produk, apakah saya harus mengembalikannya ke nilai asli?
Giuseppe
1
@ Giuseppe Tergantung apa yang Anda lakukan nanti dengan permintaan; itu lebih bersih dan akan menyebabkan lebih sedikit masalah jika Anda melakukannya
simonthesorcerer