panosdotk
11/4/2014 - 2:38 PM

Automatically assign products to parent categories

Automatically assign products to parent categories

if you want magento to automatically select the parent categories also in the manage products - categories tab when you assign the product to a child category: 

app/code/core/Mage/Catalog/Model/Product.php 

find: public function setCategoryIds (around line 293) 
replace with
<file Product.php>

this will do the work for you from now on..

If you already have hundreds of products which are assigned to only child categories and you want them to be assigned to the parent categories as well: 
1. Make backup admin/system/tools/backups/create backup 
2. Go to the phpmyadmin, make backup of the ‘catalog_product_entity’ and ‘catalog_category_product’. 
3. select the catalog_category_product, and click EMPTY… it will delete all of the records in the table! 
4. create a new file in the root folder (where the index.php is).. call it refresh.php 

run the script! http://www.yourstore.com/refresh.php 

5. go to admin: system/cache management/Rebuild Catalog Index and click Rebuild..

Delete the refresh.php file… If you move a category to an another category you should do the 5 steps again! Because, magento will keep assigned the products in the old parent categories!! 
if you have a product which is assigned to a category which has child category, and the product is not assigned to that category, the script will delete the product from the category!

you will loose the position informations for the products within the categories.. if you have them, you have to modify the code a little
public function setCategoryIds($ids)
    {
      global $categoryTree;
      
        if (!is_array($categoryTree)) {
          $categoryTree = array();
          $category = Mage::getModel('catalog/category');
          $categoryCollection = $category->getCollection();

          foreach($categoryCollection as $category) {
             $categoryTree[$category->getId()] = str_replace('/', ',', $category->getPath()).',';
          }
        }

        
        if (is_string($ids)) {
            $categoryIDs = '';
            $ids = explode(',', $ids);
            foreach ($ids as $catID) {
                if (array_key_exists($catID, $categoryTree)) {
                    $categoryIDs .= $categoryTree[$catID];
                } else {
                    $categoryIDs .= $catID.',';
                }
                   
            }
            $categoryIDs = substr($categoryIDs, 0, -1);
            $categoryIDs = array_unique(explode(',', $categoryIDs));
            
            $ids = '';
            foreach ($categoryIDs as $catId) {
                if ($catId != 1) $ids .= $catId. ','; // 1 is the ID of the ROOT category
            }
            $ids = substr($ids, 0, -1);     

            $ids = explode(',', $ids);
        } elseif (!is_array($ids)) {
            Mage::throwException(Mage::helper('catalog')->__('Invalid category IDs'));
        }
        foreach ($ids as $i=>$v) {
            if (empty($v)) {
                unset($ids[$i]);
            }
        }
        $this->setData('category_ids', $ids);
        return $this;
    }
<?php
require_once 'app/Mage.php';

umask(0);
Mage::app();

$categoryTree = array();
$category = Mage::getModel('catalog/category');
$categoryCollection = $category->getCollection();
$categoryTree = array();
$categoryTreeString = ',';
foreach($categoryCollection as $category) {
  $values = str_replace('/', ',', $category->getPath());
  $categoryTree[$category->getId()] = $values;
  $categoryTreeString .= substr($values, 0, strrpos($values, ',')).',';
}
$sql = 'SELECT entity_id, category_ids FROM catalog_product_entity';
$productCollection = Mage::getSingleton('core/resource') ->getConnection('core_read')->fetchAll($sql);
$write = Mage::getSingleton('core/resource')->getConnection('core_write');


foreach ($productCollection as $product) {
  if($product['category_ids']<>'') {
  $origCatIds = explode(',', $product['category_ids']);
    
  $newCatIds = '';
  foreach ($origCatIds as $origCatId) {
    $findTxt = ','.$origCatId. ',';
    if (strpos($categoryTreeString, $findTxt)==false) {
    
      if (array_key_exists($origCatId, $categoryTree)) {
        $newCatIds .= $categoryTree[$origCatId].',';
       } else {
        $newCatIds .= $origCatId.',';
      }
    }
  }
  $newCatIds = substr($newCatIds, 0, -1);
  $newCatIds = array_unique(explode(',', $newCatIds));
            
  $ids = '';
  foreach ($newCatIds as $catId) {
    if ($catId != 1 && array_key_exists($catId, $categoryTree)) { // 1 is the ID of the ROOT category
      $ids .= $catId. ','; 
      $sql = "INSERT INTO  `catalog_category_product` (`category_id`, `product_id`, `position`) VALUES ('". $catId. "',  '". $product['entity_id']. "',  '0');";
      $write->query($sql);
    }
  }
  $ids = substr($ids, 0, -1);
  $sql = "UPDATE  `catalog_product_entity` SET `category_ids` = '$ids' WHERE `entity_id` = ". $product['entity_id']. " LIMIT 1;";
  $write->query($sql);  
  }
}
echo 'Updated';
?>