Magento 1.9 – Set Category Product Position

categorymagento-1.9position;product

I have a php script in magento that programmatically creates products in a for each loop as below:

$i = 0;
foreach ($array as $product) {
    createProduct($params);
    $i++;
    if($i == $count){
        // finish and continue
    }
}

function createProduct($params){
    $product = new Mage_Catalog_Model_Product();
    $product->setCreatedAt(strtotime('now'));
    $product->setAttributeSetId(11);
    $product->setName(xxxxxx);
    $product->setPrice(xxxxx);
    $product->setDescription(xxxxxxx);  
    $product->setCategoryIds(array(xx,xxx));
    // and so on...

    try {
        $product->save();
    }
    catch (Exception $ex) {
        // catch error
    }

With each product i need to be able to set the category product position (see below)

How can this be done? I want to use the $i in the for each loop to be the position

enter image description here

Best Answer

There is an API class with a method specifically for this. In version 1.9.1.0 you can find the function defined in app/code/core/Mage/Catalog/Model/Category/Api.php line 467

public function assignProduct($categoryId, $productId, $position = null, $identifierType = null)

So, my recommendation is to scrap using $product->setCategoryIds() and utilize this method instead. $product->setCategoryIds() works just fine if you know ALL the categories the product should belong too, and don't care about position. However it can easily cause problems for you especially if you're doing scripting work on existing products, as it will blow out any other categories the product may have been assigned to (that you didn't supply the id for) as well as blow out the current position the product has been assigned even if the product was already associated to the category prior to performing your scripting work.

Anyways... so if we examine the method's definition, we can see that we need to already have a product id. So if we were to reference your original code, you'll want to save the product, then associate it to the category/categories.

$i = 0;
foreach ($array as $product) {
    createProduct($params, $i);
    $i++;
    if($i == $count){
        // finish and continue
    }
}

function createProduct($params, $position)
{
    $product = Mage::getModel('catalog/product');

    $product->setCreatedAt(strtotime('now'));
    $product->setAttributeSetId(11);
    $product->setName(xxxxxx);
    $product->setPrice(xxxxx);
    $product->setDescription(xxxxxxx);  

    // and so on...

    $category_ids = array('xx','xxx');

    try {
        $product->save();
        $api = Mage::getSingleton('catalog/category_api');
        foreach ($category_ids as $category_id) {
            $api->assignProduct($category_id, $product->getId(), $position);
        }
    }
    catch (Exception $ex) {
        // catch error
    }
}
Related Topic