프론트 엔드의 이벤트 옵저버에 제품을 저장하려고 할 때 마 젠토가 실패합니까?


15

이벤트 관찰자와 관련된 기능이 있습니다

요구 사항 중 하나는 주문 항목 데이터를 반복 할 때 특정 제품 속성이 비어있는 경우 별도의 모델을 통해 특정 데이터를 가져 오기위한 요청을 발행하는 것입니다 (정상 작동).

문제 코드는 기본적으로 이것으로 비등합니다.

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

그러나 마 젠토는 예외를 던지고 있습니다.

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}

magento 옵저버 외부의 타사 스크립트에서 동일한 코드를 사용할 수있는 이유는 무엇입니까?하지만 옵저버 내에서 코드를 실행하려고하면 임의의 오류 메시지와 함께 실패합니다.


이 오류는 비 배열이로 구문 분석되는 것이 일반적입니다 foreach. 스택 추적은 이벤트가 전달되었고 관찰자가 결함을 보여줍니다. 당신은시겠습니까 $order->getAllItems()을 재곡있다 array()? 사용 : Zend_Debug::dump($order->getAllItems());. 그러나 코드가 잘못된 다른 관찰자 일 수 있습니까?
ash

문제는 상단의 스 니펫이 아닌 Magento 코어 코드에 있습니다.
Zxurian

답변:


33

문제는 프론트 엔드에서 제품을 저장할 수 없다는 것입니다.

이는 프런트 엔드에 제품을로드 할 때 origData속성이 채워지지 않는다는 사실을 통해 수행됩니다 .

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

    return $this;
}

따라서 제품을 저장하려고하면 설명하는 오류가 발생합니다.

@magboy의 코드를 사용하여 현재 상점을 관리자로 변경하면이 문제를 해결할 수 있습니다.

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

더 나은 사용 Mage_Core_Model_App_Emulation

그리고 내가 선호하는 솔루션은 방법을 확장 Mage_Catalog_Model_Product하고 교체하는 setOrigData것입니다.

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

나는 여기서 다시 쓰는 것에 대해 이야기하고 있지 않다 ! 저장하려면이 곳에서만 모델을 사용하십시오. 그런 다음 보안 기능을 다른 곳에서도 계속 사용할 수 있습니다.


7

이 코드 줄을 추가하십시오.

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

현재 버전의 Magento에서 왜이 작업을 수행해야하는지 잘 모르겠습니다. 다른 사람이 설명 할 수 있습니까?


currentstore를 Admin으로 설정하고 제품을 저장 한 후 원래 값으로 다시 설정해야합니까?
Giuseppe

1
@Giuseppe 그것은 당신이 요청으로 나중에 무엇을하고 있는지에 달려 있습니다. 더 깨끗하고 더 적은 문제로 이어질 것입니다
simonthesorcerer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.