Generate a multi-lever array sub-category for a menu

You are viewing revision #3 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.

« previous (#2)

Everyone have seen a multilayer menu in several CMS

How to do that using a table ? Lets start!

your model should have id, parent_id and title, where parent_id refers to another record of the same table

Also you should create an extra relation

public function relations() {
        return array(
                         ....
			'Childs' => array(self::HAS_MANY, 'yourModel', 'parent_id'),
		);
  }

Now, in your controller (or component) create this methods

private static $menuTree = array();

   public static function getMenuTree() {
        if (empty(self::$menuTree)) {
            $rows = YourModel::model()->findAll('parent_id IS NULL');
            foreach ($rows as $item) {
                self::$menuTree[] = self::getMenuItems($item);
            }
        }
        return self::$menuTree;
    }

    private static function getMenuItems($modelRow) {

        if (!$modelRow)
            return;

        if (isset($modelRow->Childs)) {
            $chump = self::getMenuItems($modelRow->Childs);
            if ($chump != null)
                $res = array('label' => $modelRow->title, 'items' => $chump, 'url' => Yii::app()->createUrl('yourcontroller/youraction', array('id' => $modelRow->id)));
            else
                $res = array('label' => $modelRow->title, 'url' => Yii::app()->createUrl('yourcontroller/youraction', array('id' => $modelRow->id)));
            return $res;
        } else {
            if (is_array($modelRow)) {
                $arr = array();
                foreach ($modelRow as $leaves) {
                    $arr[] = self::getMenuItems($leaves);
                }
                return $arr;
            } else {
                return array('label' => ($modelRow->title), 'url' => Yii::app()->createUrl('yourcontroller/youraction', array('id' => $modelRow->id)));
            }
        }
    }

And in your theme call the first method

$this->widget('zii.widgets.CMenu', array(
              'items' =>$this->getMenuTree()
));

Now you have make a multi-layer menu