Magento - How to assign a product to a Category and It's parent categories

Posted by Damodar Bashyal on July 12, 2012

 

We not only created a lot of new categories, we deleted a lot of old categories and renamed some of them as well. Now the issue was to correctly assigning products to appropriate categories. We were provided product csv with three columns (category,sku,category-code). category-code was for SAP admins, so they can update their inventory according to code. But we need other two columns only. Here is the shell script I wrote which runs smoothly and does the work for me :-)

<?php
/**
 * Get the csv with category name and product sku and assign product to that category and it's parent.
 *
 * @category   	Technooze
 * @package     Assign Product To A Category And It's Parents
 * @copyright  	Copyright (c) 2012 Technooze.com
 * @author		Damodar Bashyal
 * @license    	http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 *
 */
require_once dirname(__FILE__) . '/../app/Mage.php';
class Mage_Shell_setCategory {
	private $_categories = array();
	private $_csv = array();
	public function run() {
		if((empty($this->_csv)) && (file_exists($csv = Mage::getBaseDir('var') . DS . 'import' . DS . 'new-categories.csv'))){
			if (($handle = fopen($csv, "r")) !== FALSE) {
				$row = 1;
				$sku = $category = $categoryCode = 0;
				while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
					if($row++ == 1){
						$data = array_flip($data);
						$sku = $data['sku'];
						$category = $data['category'];
						$categoryCode = $data['category-code'];
						continue;
					}
					$this->_csv[] = array(
					'sku' => $data[$sku],
					'category' => $data[$category],
					'categoryCode' => $data[$categoryCode],
					);
				}
				fclose($handle);
			}
		}
		$path = array();
		$rows = count($this->_csv);
		$row = 1;
		foreach($this->_csv as $k => $v){
			echo "\n\rProcessing row {$row} of {$rows}\n\r";
			$row++;
			$categoryName = $v['category'];
			$sku = $v['sku'];
			// Get Category Id and it's parent category IDs so, we can assign the product to these categories
			// Check to see if this category information has been already fetched
			if(isset($this->_categories[$categoryName])){
				$path = $this->_categories[$categoryName];
			}
			// if not, pull information about the selected category
			else {
				$categoryCollection = Mage::getResourceModel('catalog/category_collection')
				->addFieldToFilter('name', array('eq' => $categoryName))
				->addAttributeToSelect('name')
				->load();
				foreach ($categoryCollection as $category) {
					$cpath = $category->getPath();
					if(!empty($cpath)){
						$path = explode('/', $cpath);
						// remove the first element as this is root category
						array_shift($path);
						// now save this category and path, so we can re-use if needed.
						$this->_categories[$categoryName] = $path;
					}
				}
			}
			echo ($msg = $categoryName . '=>' . implode(',',$path)) . "\n\r";
			Mage::log($msg);
			// load the product collection filtered by sku
			$collectionConfigurable = Mage::getResourceModel('catalog/product_collection')
										//->addAttributeToFilter('type_id', array('eq' => 'configurable'))
										->addAttributeToFilter('sku', array('eq' => $sku))
										->addAttributeToSelect('name')
										->addAttributeToSelect('sku')
										->load();
			if(count($collectionConfigurable)){
				// now set the category ids to selected product.
				foreach ($collectionConfigurable as $product) {
					if(count($path)){
						//$product = Mage::getModel('catalog/product')->load($product->getId());
						$product->setCategoryIds($path);
						$product->save();
					}
					echo ($msg=$product->getName() . '=>' . $product->getSku() . '=>' . $product->getId()) . "\n\r";
					Mage::log($msg);
				}
			} else {
				echo ($msg='ERROR:: Invalid SKU ' . $sku) . "\n\r";
				Mage::log($msg);
			}
		}
		echo "YaY! All Done!!!\n\r";
	}
}
umask(0);
/* not Mage::run(); */
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
error_reporting(E_ALL ^ E_NOTICE);
$shell = new Mage_Shell_setCategory();
$shell->run();
// end of file:: shell/productToCategory.php

This is how i run using php command line:

shell > php productToCategory.php

Sample CSV: var/import/new-categories.csv
sku,category-code,category
AAA01RD,C-TT,t-shirts + tops
AAA03NV,C-TT,t-shirts + tops
AAA04PK,C-TT,t-shirts + tops

As, the product was always assigned to one category, the script supports one base category per product. It can be modified to support multiple base categories. It assigns to supplied category and it's parents.

And this is sample output:
Processing row 1 of 12401
t-shirts + tops => 2,3,323,336
Circus Poster Tee=>AAA01RD=>420

Also, the log is saved on the system log file.

 
not published on website


QR Code: Magento - How to assign a product to a Category and It's parent categories