web-dev-qa-db-fra.com

Ajouter par programme des produits Magento aux catégories

J'utilise Magento 1.4.0.1 . J'ai plus de 21000 produits simples, chacun étant entré dans une seule catégorie . Il existe des centaines de catégories sur mon site . Certains produits appartiennent à plusieurs catégories . Est-il possible pour moi d'ajouter des produits par programmation dans plusieurs catégories?

17
robgt

Dans le code PHP, vous pouvez les mettre dans la catégorie lors de leur importation.

Supposons que vous ayez un produit appelé $ product et un identifiant de catégorie appelé $ category_id

Vous pouvez définir les catégories auxquelles un produit appartient en procédant comme suit

$categories = array($category_id);
$product->setCategoryIds($categories);
$product->save();

Si le produit contient déjà des catégories et que vous souhaitez en ajouter une de plus, vous pouvez utiliser getCategoryIds() comme ceci:

$categories = $product->getCategoryIds();
$categories[] = $categoryId;
$product->setCategoryIds($categories);
$product->save();

Ou, comme mentionné par Joshua Peck dans les commentaires, vous pouvez utiliser le modèle category_api pour ajouter ou supprimer un produit d'une catégorie sans affecter ses attributions de catégorie actuelles:

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

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

Je veux juste ajouter que vous pouvez supprimer et ajouter avec l'API de catégorie getSingleton:

Pour supprimer un produit de la catégorie:

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

Pour ajouter un produit à une catégorie:

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

Cela n'écrasera aucune catégorie dans laquelle se trouve déjà le produit.

18
Joshua Pack

Vous pouvez écrire un module (ce qui prend du temps mais potentiellement plus rapide pour importer vos données) ou vous pouvez associer quelque chose à l'API (moins de programmation Magento mais potentiellement plus lente pour importer vos données).

Votre point de départ de ce que vous savez déjà, à quel point votre temps est précieux et à quelle fréquence vous aurez besoin d'exécuter la mise à jour devrait déterminer votre choix.

Voici la documentation de l'API Magento pour l'ajout de produits aux catégories (voir l'exemple au bas de la page):

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

2
ʍǝɥʇɐɯ

Après avoir examiné l'API de Magento: Magento ajoute les produits aux catégories de la manière suivante:

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;
}

Et obtenir tous les produits cédés:

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
Paul Hachmang

Les meilleurs points de réponse ci-dessus à utiliser Mage::getSingleton('catalog/category_api') ->assignProduct($category->getId(),$p‌​roduct->getId());

Quoi qu'il en soit, cette fonction est assez lente au cas où vous auriez beaucoup de produits/catégories à mettre à jour. 

C’est parce que la fonction assignProduct() de l’API: 

  • accepter seulement 1 produit/catégorie à la fois 
  • pour chaque appel, il charge le produit et la catégorie, puis enregistre la catégorie.
    (très lent au cas où vous auriez besoin de mettre à jour la même catégorie plusieurs fois)

Par exemple, supposons que vous vouliez affecter 10 produits à une catégorie ... cela chargera et sauvegardera la même catégorie 10 fois ...
(et chargez tous les produits qui ne sont pas réellement nécessaires si vous êtes sûr que vos identifiants de produits sont corrects)

Un moyen plus rapide
Je suis venu avec la fonction ci-dessous qui est la même que celle de l’API mais charge et enregistre la catégorie seulement une fois .

Cette fonction accepte un tableau en tant que paramètre $data qui doit contenir toutes les modifications de collecte sous la forme de $category_id => array(all the products you want to assign).

Il est facile de le personnaliser selon vos besoins en ajoutant, par exemple, un paramètre pour store_id (la fonction utilise 0 par défaut) et des informations de position sur les produits ...

Ajouter une catégorie

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();
    }
}

Supprimer la catégorie

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();
    }
}

Remarque

L'enregistrement de la catégorie déclenche les réindexations Category Flat Data et Catalog URL Rewrites (si elles sont définies en tant que update on save).
Ce n’est pas vraiment rapide (l’appel d’API fait la même chose) ...
... vous pouvez donc configurer ces réindex pour qu'ils se mettent à jour manuellement avant d'exécuter vos modifications, puis effectuez une réindexation complète sur eux après
(selon le nombre de catégories/produits que vous mettez à jour, cela pourrait être la meilleure option) 

1
WonderLand

Eh bien, j'ai fini par le faire avec l'API pour une raison de paresse. Ceci ajoute tous les produits visibles dans la catégorie avec l'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']));
  }
?>
1
ʍǝɥʇɐɯ

Nous pouvons affecter plusieurs produits à la catégorie par programmation à l'aide de scripts magento. Veuillez créer un tableau des catégories et sélectionner les produits en fonction de l'attribut personnalisé ou du champ.

$newproducts = $product->getCollection()->addAttributeToFilter(array(array('attribute'=>'attribute_label', 'eq'=> 'attribute_id')));

Parcourez les produits et assignez à la catégorie comme indiqué ci-dessous.

$newCategory = array( $list[0] , $list[$key]); 
foreach ($newproducts as $prod)
{
    $prod->setCategoryIds(array_merge($prod->getCategoryIds(), $newCategory));
    $prod->save();
}

Veuillez vous référer à my tutorial qui donne une explication étape par étape.

0
Liz Eipe C