2

我注意到 magento 的行为有些奇怪。它看起来像一个错误,或者我错过了一些东西......我做了一个简单的查询来检索产品

$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 它这样做: case 'backend': $instance = $attribute->getBackend();

检索所有属性。由于它们没有值(它们不在 addAttributeToSelect 部分中),因此它使用默认值。一种解决方案是添加 ->addAttributeToSelect('visibility') 和所有必需的属性。但是太危险了,我可能会错过一个,或者可以添加一个带有所需属性的新属性,对吗?

对我来说这是一个错误,因为默认值应该只适用于非现有属性值,但 magento 不做检查,它会执行 INSERT 或 UPDATE.. SQL: INSERT INTO catalog_product_entity_int( entity_type_id, attribute_id, store_id, entity_id, value) VALUES ( ?, ?, ?, ?, ?), (?, ?, ?, ?, ?), (?, ?, ?, ?, ?), (?, ?, ?, ?, ?) 重复键更新价值=价值(value)...

谢谢, 罗德

4

2 回答 2

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

将更改具有 id 的产品的名称12,17 and 219

于 2013-11-01T09:24:40.217 回答
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 />';
    }
}

我并不是说这是唯一的方法。但是,这按预期工作。

于 2013-11-01T09:24:31.173 回答