我使用的是Magento 1.4.0.1。 我有超过21000个简单的产品,每个产品都进入一个类别。 我的网站有数百个类别。 某些产品属于多个类别。 我有什么方法可以以编程方式将产品添加到多个类别中吗?
答案 0 :(得分:51)
在PHP代码中,您可以在导入它们时将它们放入类别中。
假设您有一个名为$ product的产品和一个名为$ category_id
的类别ID您可以通过执行以下操作来设置产品所属的类别
$categories = array($category_id);
$product->setCategoryIds($categories);
$product->save();
如果该产品已有类别,并且您想再添加一个类别,那么您可以使用getCategoryIds()
这样的内容:
$categories = $product->getCategoryIds();
$categories[] = $categoryId;
$product->setCategoryIds($categories);
$product->save();
或者,正如Joshua Peck在评论中所提到的,您可以使用category_api
模型在类别中添加或删除产品,而不会影响其当前的类别分配:
Mage::getSingleton('catalog/category_api')
->assignProduct($category->getId(),$product->getId());
Mage::getSingleton('catalog/category_api')
->removeProduct($category->getId(),$product->getId());
答案 1 :(得分:2)
您可以编写一个模块(这需要时间,但可能更快地导入数据),或者您可以将某些内容与API结合在一起(较少涉及Magento编程,但导入数据的速度可能较慢)。
您已知道的起点,您的时间以及您需要多长时间运行更新的出发点应该决定您的选择。
以下是用于向类别添加产品的Magento API文档(请参阅页面底部的示例):
http://www.magentocommerce.com/wiki/doc/webservices-api/api/catalog_category
答案 2 :(得分:1)
我最后因为某种懒惰的原因而最终使用API。这会将所有可见产品添加到ID为146的类别中
<?php
$client= new SoapClient('http://www.example.com/api/soap/?wsdl', array('trace' => 1, "connection_timeout" => 120));
// Can be added in Magento-Admin -> Web Services with role set to admin
$sess_id= $client->login('apiuser', 'apikey');
// Get the product list through SOAP
$filters = array('visibility' => '4', 'status' => '1');
$all_products=$client->call($sess_id, 'product.list', array($filters));
// Now chuck them into category 146
foreach($all_products as $product)
{ //var_dump($product);
echo $product['sku']."\n";
$doit=$client->call($sess_id, 'category.assignProduct', array('146', $product['sku']));
}
?>
答案 3 :(得分:1)
在查看Magento API之后:Magento通过以下方式将产品添加到类别中:
public function assignProduct($categoryId, $productId, $position = null, $identifierType = null)
{
$category = $this->_initCategory($categoryId);
$positions = $category->getProductsPosition();
$productId = $this->_getProductId($productId);
$positions[$productId] = $position;
$category->setPostedProducts($positions);
try {
$category->save();
} catch (Mage_Core_Exception $e) {
$this->_fault('data_invalid', $e->getMessage());
}
return true;
}
获得所有签名产品:
public function assignedProducts($categoryId, $store = null)
{
$category = $this->_initCategory($categoryId);
$storeId = $this->_getStoreId($store);
$collection = $category->setStoreId($storeId)->getProductCollection();
($storeId == 0)? $collection->addOrder('position', 'asc') : $collection->setOrder('position', 'asc');;
$result = array();
foreach ($collection as $product) {
$result[] = array(
'product_id' => $product->getId(),
'type' => $product->getTypeId(),
'set' => $product->getAttributeSetId(),
'sku' => $product->getSku(),
'position' => $product->getPosition()
);
}
return $result;
}
答案 4 :(得分:1)
以上最佳答案指向使用Mage::getSingleton('catalog/category_api')
->assignProduct($category->getId(),$product->getId());
无论如何,如果你要更新很多产品/类别,那么这个功能会很慢。
这是因为api函数assignProduct()
:
例如,假设您要将10个产品分配到1个类别...它将加载并保存相同类别10次...
(如果您确定产品ID是正确的,则加载所有实际上不需要的产品)
更快的方式
我提出了与api相同的以下功能,但只加载并保存类别一次。
此函数接受一个数组作为参数$data
,需要包含$category_id => array(all the products you want to assign)
根据您的需要定制它是微不足道的,例如,store_id
的参数(默认情况下函数使用0)和产品的位置信息......
添加类别
function assignCategories($data)
{
foreach ($data as $cat_id => $products_ids) {
/** @var $category Mage_Catalog_Model_Category */
$category = Mage::getModel('catalog/category')
->setStoreId(0)
->load($cat_id );
$positions = $category->getProductsPosition();
foreach ($products_ids as $pid) {
$positions[$pid] = null;
}
$category->setPostedProducts($positions);
$category->save();
}
}
删除类别
function removeProduct($data)
{
foreach ($data as $cat_id => $products_ids) {
/** @var $category Mage_Catalog_Model_Category */
$category = Mage::getModel('catalog/category')
->setStoreId(0)
->load($cat_id);
$positions = $category->getProductsPosition();
foreach ($products_ids as $pid) {
unset($positions[$pid]);
}
$category->setPostedProducts($positions);
$category->save();
}
}
注意强>
保存类别会触发Category Flat Data
和Catalog URL Rewrites
reindex(如果它们设置为update on save
)。
这不是很快(API调用也一样)...
...因此您可能希望在运行更改之前将这些reindex设置为手动更新,然后在完成后对它们执行完全重新索引
(根据您更新的类别/产品数量,这可能是最佳选择)
答案 5 :(得分:0)
我们可以使用magento脚本以编程方式将多个产品分配到该类别。请创建一个类别数组,然后根据自定义属性或字段选择产品。
$newproducts = $product->getCollection()->addAttributeToFilter(array(array('attribute'=>'attribute_label', 'eq'=> 'attribute_id')));
循环浏览产品并分配到类别,如下所示。
$newCategory = array( $list[0] , $list[$key]);
foreach ($newproducts as $prod)
{
$prod->setCategoryIds(array_merge($prod->getCategoryIds(), $newCategory));
$prod->save();
}
请参阅my tutorial,其中提供了逐步说明。
答案 6 :(得分:0)
为产品分配类别的最佳方式。 核心代码引用 - app\code\core\Mage\Catalog\Model\Resource\Category.php
$write = Mage::getSingleton('core/resource')->getConnection('core_write');
$categoryProductTable = Mage::getSingleton('core/resource')->getTableName('catalog/category_product');
$productData = array();$position=0;
foreach ($_productCollection as $product) {
$productData[] = array(
'category_id' => (int)$catId1,
'product_id' => (int)$product->getId(),
'position' => (int)$position
);
$productData[] = array(
'category_id' => (int)$catId2,
'product_id' => (int)$product->getId(),
'position' => (int)$position
);
}
$write->insertMultiple($categoryProductTable, $productData);