我工作的前任开发人员为所有产品分配了一个名为“delivery_text”的属性,该属性包含一串html。对于每个产品,此字符串的主体是唯一的。但是每个都包含指向特定URL的链接(每个产品的链接都相同)。由于我们的网站布局发生了变化,我们现在需要为每个产品更新此链接,而不会影响属性文本的其余部分。
显然,我不想手动编辑数千种产品只是为了更改每个产品的delivery_text字符串中链接的URL。 有没有办法可以通过编程方式为每个产品解析此属性的内容,并将指向oldsite.com/old-url的链接实例替换为指向newsite.com/new-url的链接?
我认为我可以通过某种数据库技巧来实现它,并且可以通过cpan访问phpmyadmin,但我不知道如何实际执行此操作。
请注意,我不认为这是一个重复的问题,因为虽然有很多“我如何批量更新所有产品的属性值”类型的问题,我还没有找到一个问“如何搜索和替换每个产品的属性文本中的特定字符序列“。
答案 0 :(得分:1)
如果你想从数据库中执行此操作,可以执行以下操作:
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';
这应该会显示当前数据库中所有属性值的列表。
找到所有值后,您可以使用相同的查询来替换值中的网址:
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';
您也可以使用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,所以我假设你将在admin(全局)范围内这样做:
$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因为这种方法不会创建默认值 - 它只是按照它所说的那样做;在给定的商店级别创建/更新值。