How can I programatically set the categories AND the sort order/position of products? I already have an exisiting script that iterates through my products and assigns the categories $product = Mage::getModel('catalog/product'); $product->setData($my_array_with_a_lot_of_data_including_arrayCategoryIds); $product->save();

However, this set's the sort order/position for all products to "1". I also have found this posting How to update product position (number) in specific category programmatically but I'd like to avoid loading every single category and do something like $product->setPosition($my_products_position);

Is there a way that does not require loading every single category?

PS: I want to assign the same position in every category.

3 Answers 3


You can do that writing directly to the database below is a working code that do that using an array of categories products

You have to create the array like this

            $categoryPosition[] = array('product_id' => $mageProduct->getId(),
                                        'category_id' => $categoryId,
                                        'position' => $position);

an run this code

foreach ($categoryPosition as $position){                        
            //print "Position: c=".$position['category_id']." prod=".$position['product_id']." pos=".$position['position'] . "\n";
            $query = "UPDATE tn_catalog_category_product SET position = :position "
                    . "WHERE category_id = :category_id and product_id = :product_id";
            $values = array('position' => $position['position'],
                                'category_id' => $position['category_id'],
                                'product_id' => $position['product_id']);

and remember to run the indexer catalog_category_product



There is no way of doing this, because it is harcoded here: app/code/core/Mage/Catalog/Model/Resource/Product.php:279

To change this you need to either rewrite the resource model or do a second save somehow...


Sorry but directly changing database value is very unprofessional

  1. There could be events firing when your product or category is saved
  2. Business rules will not run
  3. Validation could fail

I am sure there are many more reasons to not directly update the values.

A good solutions would be like this.

inject ProductRepository in your class

public function __construct(ProductRepository $productRepository)
/** @var \Magento\Catalog\Model\Product $product */
$product = $this->productRepository->getById(1); // fetch the product
$product->getCategory()->setPosition(1); // set its position
$this->productRepository->save($product); // save it via repository

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.