Data entry in Magento is a quite time consuming operation. Especially if you have a lot of environments and want to keep them all up to date. In this article we’ll create Magento categories tree programmatically with ability to update them without re-installing database.
First add a mysql upgrade script in your custom module:
1 2 3 4 5 6 7 |
<?php $installer = $this; $installer->startSetup(); // code will be here $installer->endSetup(); |
Then form an array with your categories and sub-categories. Pay attention – Top Category Two has a child with a same name and slug as Top Category One:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
$categories = array( array( 'name' => 'Top Category One', 'slug' => 'top-category-one', 'children' => array( array( 'name' => 'Child Category One', 'slug' => 'child-category-one', 'children' => array( array( 'name' => 'Child Sub Category One', 'slug' => 'child-sub-category-one', ), array( 'name' => 'Child Sub Category Two', 'slug' => 'child-sub-category-two', ), ), ), array( 'name' => 'Child Category Two', 'slug' => 'child-category-two', ), ), ), array( 'name' => 'Top Category Two', 'slug' => 'top-category-two', 'children' => array( array( 'name' => 'Child Category One', 'slug' => 'child-category-one', ), ), ), ); |
Next let’s write a function which will create/update the categories:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
function saveCategory($parentCategory, $data) { $updateMode = false; $categoriesCheck = Mage::getModel('catalog/category') ->getCollection() ->addAttributeToFilter('parent_id', $parentCategory->getId()) ->addAttributeToFilter('name', $data['name']) ->getFirstItem(); if ($categoryId = $categoriesCheck->getId()) { $updateMode = true; $category = Mage::getModel('catalog/category')->load($categoryId); } else { $category = Mage::getModel('catalog/category')->load(null); } if (!$updateMode) { $category->setPath($parentCategory->getPath()); } $category->setName($data['name']); $category->setDisplayMode('PRODUCTS_AND_PAGE'); $category->setIsAnchor(1); $category->setIsActive(1); $category->setIncludeInMenu(1); $category->setUrlKey($data['slug']); $category->setPageLayout('one_column'); try { $category->save(); } catch (Exception $e){ Mage::logException($e); } if (isset($data['children'])) { foreach ($data['children'] as $subCat) { saveCategory($category, $subCat); } } unset($category); } |
This function automatically pick up all children categories and run itself to create them recursively. At the beginning of the function we check if desired category already exists in scope of current parent category. If it does – update category with new values, if not – create a new one.
And last but not least add logic to walk through the categories array:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$currentStoreId = Mage::app()->getStore()->getId(); $currentUpdateMode = Mage::app()->getUpdateMode(); Mage::app()->setUpdateMode(false); Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); $store = Mage::getModel('core/store')->load(Mage_Core_Model_App::DISTRO_STORE_ID); $rootCategoryId = $store->getRootCategoryId(); $rootCategory = Mage::getModel('catalog/category')->load($rootCategoryId); // Define categories array here if (!empty($rootCategory)) { foreach ($categories as $cat) { saveCategory($rootCategory, $cat); } } // put function saveCategory() here Mage::app()->setCurrentStore($currentStoreId); Mage::app()->setUpdateMode($currentUpdateMode); |
Make sure you set current store to Mage_Core_Model_App::ADMIN_STORE_ID
and update mode to false
to avoid any errors. Then retrieve root category data and setup new categories under root. And finally return Magento to current store and set update mode back to finish upgrade.
For your convenience here is the full upgrade file listing:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
<?php $installer = $this; $installer->startSetup(); /* Define categories array */ $categories = array( array( 'name' => 'Top Category One', 'slug' => 'top-category-one', 'children' => array( array( 'name' => 'Child Category One', 'slug' => 'child-category-one', 'children' => array( array( 'name' => 'Child Sub Category One', 'slug' => 'child-sub-category-one', ), array( 'name' => 'Child Sub Category Two', 'slug' => 'child-sub-category-two', ), ), ), array( 'name' => 'Child Category Two', 'slug' => 'child-category-two', ), ), ), array( 'name' => 'Top Category Two', 'slug' => 'top-category-two', 'children' => array( array( 'name' => 'Child Category One', 'slug' => 'child-category-one', ), ), ), ); /* Perform necessary Magento mode settings */ $currentStoreId = Mage::app()->getStore()->getId(); $currentUpdateMode = Mage::app()->getUpdateMode(); Mage::app()->setUpdateMode(false); Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); /* Retrieve root category */ $store = Mage::getModel('core/store')->load(Mage_Core_Model_App::DISTRO_STORE_ID); $rootCategoryId = $store->getRootCategoryId(); $rootCategory = Mage::getModel('catalog/category')->load($rootCategoryId); /* Run category creation */ if (!empty($rootCategory)) { foreach ($categories as $cat) { saveCategory($rootCategory, $cat); } } /* Function to save categories */ function saveCategory($parentCategory, $data) { $updateMode = false; $categoriesCheck = Mage::getModel('catalog/category') ->getCollection() ->addAttributeToFilter('parent_id', $parentCategory->getId()) ->addAttributeToFilter('name', $data['name']) ->getFirstItem(); if ($categoryId = $categoriesCheck->getId()) { $updateMode = true; $category = Mage::getModel('catalog/category')->load($categoryId); } else { $category = Mage::getModel('catalog/category')->load(null); } if (!$updateMode) { $category->setPath($parentCategory->getPath()); } $category->setName($data['name']); $category->setDisplayMode('PRODUCTS_AND_PAGE'); $category->setIsAnchor(1); $category->setIsActive(1); $category->setIncludeInMenu(1); $category->setUrlKey($data['slug']); $category->setPageLayout('one_column'); try { $category->save(); } catch (Exception $e){ Mage::logException($e); } if (isset($data['children'])) { foreach ($data['children'] as $subCat) { saveCategory($category, $subCat); } } unset($category); } /* Change back Magento settings */ Mage::app()->setCurrentStore($currentStoreId); Mage::app()->setUpdateMode($currentUpdateMode); $installer->endSetup(); |
1 2 3 4 5 6 7 8 9 10 11 |
$categories = array( /* ... */ array( 'name' => 'Top Category One', 'slug' => 'top-category-one', 'display_mode' => 'PRODUCTS_AND_PAGE', 'set_is_active' => 1, 'set_include_in_menu' => 1, ), /* ... */ ); |
1 2 3 4 5 6 7 8 |
function saveCategory($parentCategory, $data) { /* ... */ $category->setDisplayMode($data['display_mode']); $category->setIsActive($data['set_is_active']); $category->setIncludeInMenu($data['set_include_in_menu']); /* ... */ } |
This is it folks, hope that help. If you find this article helpful (or vice versa) – don’t hesitate to rate it below and share to help others in their Magento journey.
If you have any suggestions – please leave a comment.