Программно добавлять продукты Magento в категории - PullRequest
17 голосов
/ 27 июня 2011

Я использую Magento 1.4.0.1. У меня более 21000 простых продуктов, каждый из которых входит в одну категорию. На моем сайте сотни категорий. Некоторые продукты относятся к нескольким категориям. Есть ли какой-то способ для меня программно добавлять продукты в несколько категорий?

Ответы [ 7 ]

51 голосов
/ 28 июня 2011

В коде 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(),$p‌​roduct->getId());

Mage::getSingleton('catalog/category_api')
  ->removeProduct($category->getId(),$p‌​roduct->getId());
18 голосов
/ 29 апреля 2015

Я просто хочу добавить, что вы можете удалить и добавить с помощью API getSingleton category:

Удалить товар из категории:

Mage::getSingleton('catalog/category_api')->removeProduct($category->getId(),$p‌​roduct->getId());

Добавить товар в категорию:

Mage::getSingleton('catalog/category_api')->assignProduct($category->getId(),$p‌​roduct->getId());

Это не перезапишет никакие категории, к которым относится продукт

2 голосов
/ 27 июня 2011

Вы можете написать модуль (который требует времени, но, возможно, быстрее при импорте ваших данных), или вы можете соединить что-то с API (меньше вовлекает программирование на Magento, но потенциально медленнее при импорте ваших данных).

Ваша исходная точка того, что вы уже знаете, насколько ценно ваше время и как часто вам нужно будет запускать обновление, должна определять ваш выбор.

Вот документация по Magento API для добавления товаров в категории (см. Пример внизу страницы):

http://www.magentocommerce.com/wiki/doc/webservices-api/api/catalog_category

1 голос
/ 27 октября 2017

Лучшие из приведенных выше точек ответа: Mage::getSingleton('catalog/category_api') ->assignProduct($category->getId(),$p‌​roduct->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 делает то же самое) ...
... так что вы можете настроить обновление этих индексов вручную перед выполнением изменений, а затем выполнить полную переиндексацию для них после
(в зависимости от количества обновляемых категорий / продуктов это может быть лучшеопция)

1 голос
/ 16 апреля 2012

После просмотра 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;
}
1 голос
/ 18 октября 2011

Ну, я закончил тем, что делал это с 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']));
  }
?>
0 голосов
/ 26 октября 2016

Мы можем назначить несколько продуктов в категорию программно с помощью сценариев 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();
}

Пожалуйста, обратитесь к моему учебнику , в котором приводится пошаговое объяснение.

...