Magento Certified Developer GuideCategory: 7. CatalogHow is the category parent id, path set on new categories?
Manish Prakash Staff asked 5 years ago

So when ever we add a new category through admin, the form already as ‘path’ set upto the current category in hidden field.
So lets say we are adding a sub category to the rootCatalog, in that case path would be ‘1’ in the hidden field.
After form submit, through POST this gets set into the Category Object.

Next in the _beforeSave() function of category model

protected function _beforeSave(Varien_Object $object)
    {
        parent::_beforeSave($object);

        if (!$object->getChildrenCount()) {
            $object->setChildrenCount(0);
        }
        if ($object->getLevel() === null) {
            $object->setLevel(1);
        }

        if (!$object->getId()) {
            $object->setPosition($this->_getMaxPosition($object->getPath()) + 1);
            $path  = explode('/', $object->getPath());
            $level = count($path);
            $object->setLevel($level);
            if ($level) {
                $object->setParentId($path[$level - 1]);
            }
            $object->setPath($object->getPath() . '/');

            $toUpdateChild = explode('/',$object->getPath());

            $this->_getWriteAdapter()->update(
                $this->getEntityTable(),
                array('children_count'  => new Zend_Db_Expr('children_count+1')),
                array('entity_id IN(?)' => $toUpdateChild)
            );

        }
        return $this;
    }

Here you can see how the ‘position’, ‘level’, ‘parent_id’, etc attributes are set.
Next we have the _afterSave() function which will see the full final path

protected function _afterSave(Varien_Object $object)
    {
        /**
         * Add identifier for new category
         */
        if (substr($object->getPath(), -1) == '/') {
            $object->setPath($object->getPath() . $object->getId());
            $this->_savePath($object);
        }

        $this->_saveCategoryProducts($object);
        return parent::_afterSave($object);
    }