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