2013-11-01 68 views
2

我注意到magento行爲中有些奇怪的東西。 它看起來像任何一個錯誤,或者我錯過了什麼...... 我做一個簡單的查詢中檢索產品magento Bug與資源集合

$collection = Mage::getResourceModel('catalog/product_collection')           
             ->addAttributeToSelect('price') 
             ->addAttributeToSelect('sku') 
             ->addAttributeToSelect('name') 
             ->addAttributeToFilter(array(array(
               'attribute' => 'my_attribute', 
               'eq' => 'my_value'   ) 
              )); 
//Then I update 
foreach($collection as $_product){ 
    $_product->setData("name","my_other_val"); 
    $_product->save(); 
} 

的Magento不僅將更新「名」,它將更新所有必填字段並設置默認值!! 因此,例如,它將「可見性」屬性更改爲「搜索目錄」,而產品具有另一種可見性! 我現在已經混亂了我的可配置產品,它也改變了其他屬性。

你如何解釋這一點?

我沒有反向和屬性的整個列表,同時節省該產品被檢索,在該方法中: walkAttributes 它這樣做: 情況下「後端」: $實例= $屬性 - > getBackend();

其中檢索所有屬性。由於它們沒有值(它們不在addAttributeToSelect部分中),因此它使用默認值。 一個解決方案是添加 - > addAttributeToSelect('visibility') 和所有必需的屬性。 但是太危險了,我可能會錯過一個,或者一個新的屬性可以添加所需的屬性嗎?

對我來說這是一個錯誤,因爲默認值應該只適用於非現有屬性值,但Magento的沒有做的檢查,它這個查詢其插入或更新.. SQL:INSERT INTO catalog_product_entity_intentity_type_id (?,?,?,?,?),(?,?,?,?,?),????????????????????????????????????????????????? ,?,?,?)ON DUPLICATE密鑰更新值= VALUES(value) ...

謝謝, 杆

回答

2

這不是一個錯誤。這實際上是一個功能。在加載產品集合時,出於性能原因,並非所有屬性都加載了該產品。
爲了能夠保存它,你需要撥打$product->load($id),然後$product->save()
此外,您還必須確保您在ID爲0的商店下運行腳本(admin)。保存僅適用於此。將其添加到腳本頂部

Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID)); 

但是,這裏有一個其他的想法。請勿使用save。這很慢,如果你不小心,你可以造成一些傷害。改用它。

Mage::getSingleton('catalog/product_action')->updateAttributes($productIds, $attributes, $storeId); 

即使您不在管理存儲區上,它也能正常工作,並且它只會更改您指定的屬性。這是什麼參數意味着:

$productIds - 您需要更改產品id的數組。 array(12, 17, 219)
$attributes - 您想要更改的陣列array('name'=>'Your name here', 'description'=>'Your description here')
$storeId - 您進行更改的存儲的ID。默認值使用0

注意:如果要爲不同產品設置不同的屬性值,則需要爲每個屬性值調用此屬性值。
例如呼叫:

Mage::getSingleton('catalog/product_action')->updateAttributes(array(12, 17, 219), array('name'=>'Your name here'), 0); 

將產品12,17 and 219

+0

嘿!這是太棒了!!感謝分享這個。我喜歡它:-)我目前正在使用「core_write」和手動更新查詢來達到特定進程的良好性能,但是您剛纔在這裏描述的那個非常棒!再次感謝。竿 – Rod

0

您應該做的是在顯式加載後從收集結果更新產品。

這裏是我的意思的例子:

$product_collection = Mage::getModel('catalog/product') 
    ->getCollection() 
    ->addAttributeToFilter(array(array(
     'attribute' => 'my_attribute', 
     'eq' => 'my_value' 
    ))); 

foreach ($product_collection as $p) { 
    $product = Mage::getModel('catalog/product')->load(
     $p->getId() 
    ); 
    $product->setName('NEW NAME HERE'); 
    try { 
     $product->save(); 
     echo 'Product '. $product->getSku() .' has been updated.<br />'; 
    } catch (Exception $e) { 
     echo 'Failed to update product '. $product->getSku() .' - '. $e->getMessage() .'<br />'; 
    } 
} 

我不是說這是做到這一點的唯一方法;然而這按預期工作。

+0

感謝您的快速回答更改名稱與ID,其實這正是我只是做了。所以我現在明白,這不是一個錯誤,而是一個規則,你必須在任何更新之前加載。這對我來說是新的。謝謝。棒 – Rod