Magento falhando ao tentar salvar o produto dentro do observador de eventos no frontend?

15

Eu tenho uma função que está ligada a um observador de eventos

Um dos requisitos é que, quando ele percorre os dados do item do pedido, se um determinado atributo do produto estiver vazio, ele emite uma solicitação para obter dados específicos por meio de um modelo separado (funcionando bem).

o código do problema basicamente se resume a isso

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();
}

no entanto Magento está lançando uma exceção de

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}

Por que eu seria capaz de usar código idêntico em um script de terceiros fora do observador magento, mas quando tento executá-lo nesse observador, ele falha com essa mensagem de erro aleatória?

Zxuriano
fonte
Este erro é típico de uma não matriz sendo analisada foreach. O rastreamento de pilha mostra que um evento é despachado e o observador está com defeito. Tem certeza de que $order->getAllItems()está retuneando um array()? usar: Zend_Debug::dump($order->getAllItems());. No entanto, pode ser outro observador com algum código incorreto?
cinzas
o problema está no código principal do Magento, não no meu snippet na parte superior.
Zxurian 7/03/14

Respostas:

33

O problema é que você não tem permissão para salvar produtos do frontend.

Isso é feito pelo fato de que, quando você carrega um produto no front-end, a origDatapropriedade não é preenchida:

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

    return $this;
}

Portanto, quando você tenta salvar o produto, o erro que você descreve é ​​gerado.

Você pode resolver esse problema ao alterar a loja atual para admin, por exemplo, com o código de @magboy:

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

melhor usando Mage_Core_Model_App_Emulation

E minha solução preferida é estender Mage_Catalog_Model_Producte substituir o setOrigDatamétodo

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

Eu não estou falando de reescrever aqui! Use apenas o seu modelo neste local para ativar o salvamento. Então você tem o recurso de segurança ainda ativo em qualquer outro lugar.

Fabian Blechschmidt
fonte
7

Tente adicionar esta linha de código:

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

Não sei por que você precisa fazer isso agora na versão atual do Magento. Talvez alguém possa explicar?

magboy
fonte
depois de definir o currentstore como Admin e salvar o produto, preciso defini-lo novamente para o valor original?
Giuseppe
11
@ Giuseppe Depende do que você está fazendo mais tarde com a solicitação; É mais limpo e vai levar a menos problemas se você fizer isso
simonthesorcerer