Программно добавить продукты в Magento в категориях
Я использую Magento 1.4.0.1. У меня есть более 21000 простых продуктов, каждый из которых входит в одну категорию. На моем сайте сотни категорий. Некоторые продукты относятся к нескольким категориям. Есть ли способ для меня, чтобы программно добавить товар в несколько категорий?
7 ответов
в PHP-коде вы можете поместить их в категорию во время импорта.
скажем, у вас есть продукт под названием $product и идентификатор категории под названием $category_id
вы можете установить категории, к которым принадлежит продукт, выполнив следующие действия
$categories = array($category_id);
$product->setCategoryIds($categories);
$product->save();
если продукт уже имеет категории, и вы хотите добавить еще один, то вы можете использовать getCategoryIds()
такой:
$categories = $product->getCategoryIds();
$categories[] = $categoryId;
$product->setCategoryIds($categories);
$product->save();
или, как говорил Джошуа Пек в комментариях, вы можете использовать the category_api
модель для добавления или удаления продукта из категории, не затрагивая его текущие назначения категорий:
Mage::getSingleton('catalog/category_api')
->assignProduct($category->getId(),$product->getId());
Mage::getSingleton('catalog/category_api')
->removeProduct($category->getId(),$product->getId());
Я просто хочу добавить, что вы можете удалить и добавить с помощью getSingleton category API:
чтобы удалить продукт из категории:
Mage::getSingleton('catalog/category_api')->removeProduct($category->getId(),$product->getId());
добавить продукт в категорию:
Mage::getSingleton('catalog/category_api')->assignProduct($category->getId(),$product->getId());
это не будет перезаписывать какие-либо категории продукт уже находится в
вы можете написать модуль (который занимает время, но потенциально быстрее при импорте ваших данных) или вы можете что-то вместе с API (меньше вовлечения программирования Magento, но потенциально медленнее при импорте ваших данных).
ваша отправная точка того, что вы уже знаете, насколько ценно ваше время и как часто вам нужно будет запускать обновление, должна определить ваш выбор.
вот документация Magento API для добавления продуктов в категории (см. пример внизу страницы):
http://www.magentocommerce.com/wiki/doc/webservices-api/api/catalog_category
Ну, я закончил делать это с 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']));
}
?>
после просмотра 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;
}
и получать все asigned продукты:
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;
}
мы можем назначить несколько продуктов категории программно, используя сценарии 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();
}
см. мой учебник что дает пошаговое объяснение.
лучший ответ для Mage::getSingleton('catalog/category_api')
->assignProduct($category->getId(),$product->getId());
в любом случае эта функция довольно медленная, если у вас есть много продуктов/категорий для обновления.
это потому, что функция api assignProduct()
:
- только примите 1 продукт / категорию во время
- для каждого вызова он загружает продукт и категорию, а затем сохраните категория
(очень медленно, если вам нужно обновить одну и ту же категорию несколько раз )
например, предположим, что вы хотите присвоить 10 продуктов 1 категории ... он загрузится и сохранит ту же категорию 10 раз ...
(и загрузите весь продукт, который на самом деле не требуется, если вы уверены, что идентификаторы продукта исправлены)
быстрее
Я придумал функцию ниже, которая такая же, как 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();
}
}
Примечание
сохранение триггера категории the Category Flat Data
и Catalog URL Rewrites
reindex ( если они установлены как update on save
).
Это не совсем быстро (вызов API делает то же самое ) ...
... таким образом, вы можете установить эти reindex для обновления вручную перед запуском изменений, а затем сделать полный reindex на них после
(в зависимости от количества категорий/продуктов, которые вы обновляете, это может быть лучшим вариантом )