├── README.md └── shell └── import_categories.php /README.md: -------------------------------------------------------------------------------- 1 | Full overview here: http://www.bubblecode.net/en/2012/04/16/magento-import-categories-from-cli/ 2 | -------------------------------------------------------------------------------- /shell/import_categories.php: -------------------------------------------------------------------------------- 1 | getStore($storeCode); 23 | } catch (Mage_Core_Model_Store_Exception $e) { 24 | Mage::throwException(sprintf("Could not find store with code '%s'", $storeCode)); 25 | } 26 | } 27 | 28 | /** 29 | * Prepares default data of new category with specified name. 30 | * 31 | * @param string $name 32 | * @return array 33 | */ 34 | protected function _prepareCategoryData($name) 35 | { 36 | return array( 37 | 'name' => trim($name), 38 | 'is_active' => 1, 39 | 'include_in_menu' => 1, 40 | 'is_anchor' => 0, 41 | 'url_key' => '', 42 | 'description' => '', 43 | ); 44 | } 45 | 46 | /** 47 | * Creates new category. 48 | * 49 | * @param int $parentId 50 | * @param string $name 51 | * @param int $storeId 52 | * @return Mage_Catalog_Model_Category 53 | */ 54 | protected function _createCategory($parentId, $name, $storeId) 55 | { 56 | $category = Mage::getModel('catalog/category'); 57 | /* @var $category Mage_Catalog_Model_Category */ 58 | 59 | $data = $this->_prepareCategoryData($name); 60 | $parent = Mage::getModel('catalog/category')->load($parentId); 61 | 62 | $category->setData($data) 63 | ->setAttributeSetId($category->getDefaultAttributeSetId()) 64 | ->setStoreId($storeId) 65 | ->setPath(implode('/', $parent->getPathIds())) 66 | ->setParentId($parentId) 67 | ->save(); 68 | 69 | return $category; 70 | } 71 | 72 | /** 73 | * Process some stuff before running categories import. 74 | */ 75 | protected function _beforeProcess() 76 | { 77 | // Needed for correct creation of categories url rewrites. 78 | $processes = Mage::getSingleton('index/indexer')->getProcessesCollection(); 79 | $processes->walk('setMode', array(Mage_Index_Model_Process::MODE_MANUAL)); 80 | $processes->walk('save'); 81 | } 82 | 83 | /** 84 | * Process some stuff after running categories import. 85 | */ 86 | protected function _afterProcess() 87 | { 88 | $processes = Mage::getSingleton('index/indexer')->getProcessesCollection(); 89 | $processes->walk('setMode', array(Mage_Index_Model_Process::MODE_REAL_TIME)); 90 | $processes->walk('save'); 91 | 92 | echo PHP_EOL . 'Reindexing all...' . PHP_EOL; 93 | $processes->walk('reindexAll'); 94 | } 95 | 96 | /** 97 | * Displays critical message and exit. 98 | */ 99 | protected function _fault($msg) 100 | { 101 | exit(PHP_EOL . $msg . PHP_EOL); 102 | } 103 | 104 | /** 105 | * Main script method that imports all categories from specified CSV file. 106 | */ 107 | public function run() 108 | { 109 | $start = microtime(true); 110 | 111 | if (!$file = $this->getArg('f')) { 112 | echo $this->usageHelp(); 113 | } else { 114 | $delimiter = $this->getArg('d') ? $this->getArg('d') : ','; 115 | $enclosure = $this->getArg('e') ? $this->getArg('e') : '"'; 116 | 117 | $file = Mage::getBaseDir() . '/' . $file; 118 | if (!file_exists($file)) { 119 | $this->_fault("File $file doest not exists."); 120 | } elseif (!is_readable($file)) { 121 | $this->_fault("File $file is not readable."); 122 | } 123 | 124 | $fh = fopen($file, 'r'); 125 | if (!$fh) { 126 | $this->_fault("An error occured opening file $file."); 127 | } 128 | 129 | $collection = Mage::getModel('catalog/category')->getCollection() 130 | ->addFieldToFilter('level', 2); 131 | if ($collection->count() > 0) { 132 | if (!$this->getArg('force')) { 133 | $this->_fault('Categories already created. Use --force option to delete old categories automatically.'); 134 | } else { 135 | $collection->walk('delete'); 136 | echo 'Deleted old categories' . PHP_EOL; 137 | } 138 | } 139 | 140 | try { 141 | $line = 0; 142 | $otherStoreCodes = array(); 143 | $rootId = Mage::app()->getDefaultStoreView()->getRootCategoryId(); 144 | $parentIds = array(0 => $rootId); 145 | 146 | $this->_beforeProcess(); 147 | 148 | while ($data = fgetcsv($fh, null, $delimiter, $enclosure)) { 149 | $line++; 150 | 151 | if ($line === 1 && ($this->getArg('t') || empty($data[0]))) { 152 | $otherStoreCodes = array_filter($data); // will keep store column number and store code 153 | continue; 154 | } 155 | 156 | foreach ($data as $i => $value) { 157 | if (!empty($otherStoreCodes) && $i >= min(array_keys($otherStoreCodes))) { 158 | break; 159 | } 160 | $label = trim($value); 161 | if (empty($label)) { 162 | continue; 163 | } 164 | $parentId = $parentIds[$i]; 165 | $category = $this->_createCategory($parentId, $label, 0); 166 | $parentIds[$i + 1] = $category->getId(); 167 | echo str_repeat('--', $i + 1) . ' ' . $label; 168 | foreach ($otherStoreCodes as $j => $storeCode) { 169 | $label = trim($data[$j]); 170 | if (!empty($label)) { 171 | $category->setStoreId($this->_getStore($storeCode)->getId()) 172 | ->setUrlKey('') 173 | ->setName($label) 174 | ->save(); 175 | printf(' [%s: %s]', $storeCode, $label); 176 | } 177 | } 178 | echo PHP_EOL; 179 | } 180 | } 181 | 182 | $this->_afterProcess(); 183 | } catch (Exception $e) { 184 | Mage::logException($e); 185 | $this->_fault($e->getMessage()); 186 | } 187 | } 188 | 189 | $end = microtime(true); 190 | $time = $end - $start; 191 | echo PHP_EOL; 192 | echo 'Script Start: ' . date('H:i:s', $start) . PHP_EOL; 193 | echo 'Script End: ' . date('H:i:s', $end) . PHP_EOL; 194 | echo 'Duration: ' . number_format($time, 3) . ' sec' . PHP_EOL; 195 | } 196 | 197 | /** 198 | * List of available script options. 199 | * 200 | * @return string 201 | */ 202 | public function usageHelp() 203 | { 204 | return <<< USAGE 205 | Usage: php -f import_categories.php -- [options] 206 | 207 | -f File to import 208 | -d Delimiter (default is ,) 209 | -e Enclosure (default is ") 210 | -t Enable store translations in first line 211 | --force Delete old categories and create new ones 212 | -h Short alias for help 213 | help This help 214 | 215 | USAGE; 216 | } 217 | } 218 | 219 | if (php_sapi_name() != 'cli') { 220 | exit('Run it from cli.'); 221 | } 222 | 223 | $shell = new Mage_Shell_ImportCategories(); 224 | $shell->run(); 225 | --------------------------------------------------------------------------------