Agregue programáticamente productos de Magento a categorías
categories (7)
Bueno, terminé haciendo esto con la API por alguna razón de pereza. Esto agrega todos los productos visibles en la categoría con 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'']));
}
?>
Estoy usando Magento 1.4.0.1. Tengo más de 21000 productos simples, cada uno ingresado en una sola categoría. Hay cientos de categorías en mi sitio. Algunos productos pertenecen a múltiples categorías. ¿Hay alguna forma de agregar productos en múltiples categorías mediante programación?
Después de buscar en la API de Magento: Magento agrega productos a las categorías de la siguiente manera:
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;
}
Y consiguiendo todos los productos asignados:
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;
}
En el código PHP puede colocarlos en la categoría mientras los importa.
Digamos que tienes un producto llamado $ product y un ID de categoría llamado $ category_id
Puede establecer las categorías a las que pertenece un producto haciendo lo siguiente
$categories = array($category_id);
$product->setCategoryIds($categories);
$product->save();
Si el producto ya tiene categorías y desea agregar una más, puede usar getCategoryIds()
siguiente manera:
$categories = $product->getCategoryIds();
$categories[] = $categoryId;
$product->setCategoryIds($categories);
$product->save();
O, como lo mencionó Joshua Peck en los comentarios, puede usar el modelo category_api
para agregar o eliminar un producto de una categoría sin afectar sus asignaciones de categoría actuales:
Mage::getSingleton(''catalog/category_api'')
->assignProduct($category->getId(),$product->getId());
Mage::getSingleton(''catalog/category_api'')
->removeProduct($category->getId(),$product->getId());
Los mejores puntos de respuesta anteriores para usar Mage::getSingleton(''catalog/category_api'') ->assignProduct($category->getId(),$product->getId());
De todos modos, esa función es bastante lenta en caso de que tenga muchos productos / categorías para actualizar.
Esto se debe a que la función api assignProduct()
:
- solo acepta 1 producto / categoria a la vez
- para cada llamada carga el producto y la categoría y luego guarda la categoría
(muy lento en caso de que necesite actualizar la misma categoría varias veces)
Por ejemplo, suponga que desea asignar 10 productos a 1 categoría ... se cargará y guardará la misma categoría 10 veces ...
(y cargue todos los productos que no sean realmente necesarios si está seguro de que los ID de los productos son correctos)
Una manera mas rapida
Se me ocurrió la siguiente función que es la misma que la API, pero carga y guarda la categoría solo una vez .
Esta función acepta una matriz como parámetro $data
que deben contener todos los cambios recopilados en forma de $category_id => array(all the products you want to assign)
Es trivial personalizarlo según sus necesidades agregando, por ejemplo, un parámetro para store_id
(la función usa 0 por defecto) y la información de posición de los productos ...
Añadir categoría
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();
}
}
Eliminar categoría
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();
}
}
Nota
Al guardar la categoría, se Catalog URL Rewrites
Category Flat Data
y las Catalog URL Rewrites
(si están configuradas como update on save
).
Esto no es exactamente rápido (la llamada a la API hace lo mismo) ...
... así que es posible que desee configurar estos reindexaciones para que se actualicen manualmente antes de ejecutar los cambios y luego realizar una reindexación completa en ellos después de
(Dependiendo de la cantidad de categorías / productos que esté actualizando, esta podría ser la mejor opción)
Podemos asignar múltiples productos a la categoría mediante programación usando scripts de magento. Cree una matriz de las categorías y seleccione los productos en función del atributo o campo personalizado.
$newproducts = $product->getCollection()->addAttributeToFilter(array(array(''attribute''=>''attribute_label'', ''eq''=> ''attribute_id'')));
Recorra los productos y asigne la categoría como se muestra a continuación.
$newCategory = array( $list[0] , $list[$key]);
foreach ($newproducts as $prod)
{
$prod->setCategoryIds(array_merge($prod->getCategoryIds(), $newCategory));
$prod->save();
}
Por favor, consulte mi tutorial que da una explicación paso a paso.
Puede escribir un módulo (lo que lleva tiempo pero potencialmente más rápido en la importación de sus datos) o puede poner algo junto con la API (menos involucra la programación de Magento pero potencialmente más lento al importar sus datos).
Su punto de partida de lo que ya sabe, lo valioso que es su tiempo y la frecuencia con la que necesitará ejecutar la actualización debería determinar su elección.
Aquí está la documentación de la API de Magento para agregar productos a categorías (vea el ejemplo al pie de la página):
http://www.magentocommerce.com/wiki/doc/webservices-api/api/catalog_category
Solo quiero agregar que puede eliminar y agregar con la API de categoría getSingleton:
Para eliminar el producto de la categoría:
Mage::getSingleton(''catalog/category_api'')->removeProduct($category->getId(),$product->getId());
Para agregar producto a la categoría:
Mage::getSingleton(''catalog/category_api'')->assignProduct($category->getId(),$product->getId());
Esto no sobrescribirá ninguna categoría en la que el producto ya se encuentre