Лучшие из приведенных выше точек ответа: Mage::getSingleton('catalog/category_api')
->assignProduct($category->getId(),$product->getId());
В любом случае, эта функция работает довольно медленно, если у вас есть много продуктов / категорий для обновления.
Это потому, что функция API assignProduct()
:
- принимает только 1 продукт / категорию за раз
- для каждого вызова, который загружает продукт и категорию изатем сохраните категорию
(очень медленно, если вам нужно обновить одну и ту же категорию несколько раз)
Например, предположим, что вы хотите назначить 10 продуктов в одну категорию ... она будет загружена исохранить одну и ту же категорию 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
(если они установлены как update on save
).
Это не совсем быстро (вызов API делает то же самое) ...
... так что вы можете настроить обновление этих индексов вручную перед выполнением изменений, а затем выполнить полную переиндексацию для них после
(в зависимости от количества обновляемых категорий / продуктов это может быть лучшеопция)