In my Magento installation, I have created two root categories, one for each website.

Let's say in my UK website, it use root category that has categoryID 2. In my US website, it uses root category that has categoryID 100.

I can successfully assign a product to a category within root category 2. And the problem is, if I want to give this product to another category within root category 100, it will just remove the product from root category 2, and then add to root category 100. This is not what I want, I want to keep the product in both categories, instead of moving it around.

This is the code I'm using to update products. What should I change so it will add the product to a new category while still keeping the product in the old category?

    private function updateProductData(array $data, ProductAbstract $product)

    $_rootcatID = $this->util->getRootCategoryIdByWebsiteId($data['dataarea']);
    $category = \Mage::getModel('catalog/category')
        ->addAttributeToFilter('custom_category', 'IG' . $data['category_id'])
        ->addFieldToFilter('path', array('like'=> "1/$_rootcatID/%"))

    $path = '';
    if ($category->getId()) {
        $path = $category->getPath();
        $path = str_replace("1/$_rootcatID/", '', $path);
        $path = explode('/', $path);

        foreach ($path as $idx => $segment) {
            $path[$idx] = $this->getCategoryName($segment);

        $path = implode('/', $path);
    $name = str_replace('||', "\n", $data['name']);
    $name = trim($name);
    $name = str_replace("\n", " - ", $name);

    //Take multiple websites into consideration
    // Get website for existing SKU.
    $_product = \Mage::getModel('catalog/product');
    $websiteIds = $_product->getWebsiteIds();

    foreach($websiteIds as $websiteId){
        $_websites .= \Mage::getModel('core/website')->load($websiteId)->getData("code") . ",";

    $_websites = $_websites . $this->util->getWebsiteCode($data['dataarea']);

    $product->set('name', $name)
        ->set('sku', $data['sku'])
        ->set('is_in_stock', 1)
        ->set('visibility', DataInterface::VISIBILITY_CATALOG_SEARCH)
        ->set('tax_class_id', 'Taxable Goods')
        ->set('store', $this->util->getStoreCode($data['dataarea']))
        ->set('weight', $data['net_weight'])
        ->set('url_key', $this->getUrlKeyFromName($data['name']))
        ->set('is_qty_decimal', $data['qty_is_decimal'])
        ->set('status', 1);

    //add the product to the correct category by id
    //(if 2 categories has the same name, it might use the wrong category which might me inactive)
    if ($category->getId()) {
      $product->set('category_ids', $category->getId());
    } else {
      $product->set('categories', $path);

    foreach ($this->plainAttributes as $plain) {
        $product->set($plain, $data[$plain]);
  • I'm guessing that each category root is the root for a different website? If so, you need to load the product in the context of the site to set its data. – Douglas Radburn Feb 26 '18 at 14:38
  • Any reason why you're creating the category paths and not just assigning the categories? – Douglas Radburn Feb 26 '18 at 14:42

You need to load the product in the context of the website ID to save the category for that product (against that store). Something like

$allStores = Mage::app()->getStores();

foreach ($allStores as $_storeId => $storeValue)
    $_theStoreId = Mage::app()->getStore($_storeId)->getId();

    $_product = Mage::getModel('catalog/product')->load(1234)->setWebsiteId($_theStoreId);

    $storeSpecificCategories = $_product->getCategoryIds();

    // add new category but keep existing
    $storeSpecificCategories[] = '234567';

    $_product->setData('category_ids', $storeSpecificCategories);


Looking at your initial collection, you should also limit the SQL response by setting the pagesize and currentpage. Otherwise, it might load a larger dataset that you expect into memory:

$category = \Mage::getModel('catalog/category')
    ->addAttributeToFilter('custom_category', 'IG' . $data['category_id'])
    ->addFieldToFilter('path', array('like'=> "1/$_rootcatID/%"))
  • Thanks for your code, but I have already taken different stores into consideration. The problem is it still moving the products to different categories instead of keeping itself in all categories. I can successfully add product to UK website and in it's root category, and I can successfully add the same product to US website and in it's root category. But i can't keep the products in both root categories. It's being moved back and forth. – Magento Learner Feb 26 '18 at 16:53
  • Have you loaded the product for the store as per my example above? – Douglas Radburn Feb 27 '18 at 9:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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