商品属性文字批量更新

Mass update of product attribute text

我工作的前任开发人员为所有产品分配了一个名为 "delivery_text" 的属性,其中包含 html 的字符串。对于每个产品,此字符串的主体都是唯一的。但是,每个都包含一个 link 到特定的 url(每个产品的 link 都相同)。由于我们网站布局的变化,我们现在需要为每个产品更新这个 link,而不影响属性文本的其余部分。

显然,我不想为了更改每个产品 delivery_text 字符串中 link 的 url 而手动编辑数千个产品。 有没有一种方法可以以编程方式为每个产品解析此属性的内容,并将 links 的实例替换为 oldsite.com/old-url ,将 links 替换为 newsite.com/new-url ?

我想我可以通过某种数据库技巧来做到这一点,并且可以通过 cpan 访问 phpmyadmin,但我不知道如何真正去做。

请注意,我不认为这是一个重复的问题,因为虽然有很多 "how do i mass update attribute values for all products" 类型的问题,但我还没有找到一个问 "how do i search and replace a specific character sequence within the attribute text for each product" 的问题。

如果您想从数据库中执行此操作,您可以这样做:

查找属性值

SELECT at.* FROM catalog_product_entity_varchar AS at
INNER JOIN eav_attribute AS ea
  ON ea.attribute_id = at.attribute_id
WHERE ea.attribute_code = 'delivery_text';

这应该会显示当前数据库中所有属性值的列表。

更新属性值

找到所有值后,您可以使用相同的查询来替换值中的 URL:

UPDATE catalog_product_entity_varchar AS at
INNER JOIN eav_attribute AS ea
  ON ea.attribute_id = at.attribute_id
SET at.value = REPLACE(at.value, 'http://oldurl.com', 'http://newurl.com')
WHERE ea.attribute_code = 'delivery_text';

没有SQL

您也可以使用 Magento 模型 API 执行此操作。首先收集您需要的数据,方法同上:

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

$collection = Mage::getModel('catalog/product')
    ->getCollection()
    ->addAttributeToSelect('delivery_text');

foreach ($collection as $product) { /** @var Mage_Catalog_Model_Product $product */
    var_dump($product->getDeliveryText());
}

然后您可以更新循环中的属性。在这里您需要指定一个商店 ID,所以我假设您将在管理(全局)范围内执行此操作:

$old = 'http://oldurl.com';
$new = 'http://newurl.com';

foreach ($collection as $product) { /** @var Mage_Catalog_Model_Product $product */
    Mage::getModel('catalog/product_action')
        ->updateAttributes(
            array($product->getId()), 
            array('delivery_text' => $new),
            Mage_Core_Model_App::ADMIN_STORE_ID
        );
}

请注意: 使用 Mage_Catalog_Model_Product_Action::updateAttributes 可以快速有效地更新给定商店级别的产品属性,但如果您没有使用管理商店级别,则you may not be able to retrieve the value in a collection 因为此方法不会创建默认值 - 它只是按照它所说的去做; create/update 给定商店级别的值。