Hierarchy

I am wondering how I could allow my pages to be in hierarchy. I have a table ‘page’ in my DB with a column ‘childOf’.

Now, is there any way I could specify a relation within the Page model to the childOf field in the same table? If yes, then how? And how could I update the menu component provided by Yii (modified) to reflect this change?

The current code of the component is-




class MainMenu extends CWidget

{

	/**

	 * (non-PHPdoc)

	 * @see framework/web/widgets/CWidget#run()

	 */

	public function run()

	{

		$items1=array(array('label'=>'Home', 'url'=>array('/site/index'), 'visible'=>true));


		foreach(Page::model()->findAll() as $item)

		{

			 $items1[] = array('label'=>$item->title, 'url'=>array('/page/show', array('id'=>$item->id)), 'visible'=>true);

		}

		


		$items1 = array_merge($items1, array(

		array('label'=>'Contact', 'url'=>array('/site/contact'), 'visible'=>true),

		array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest),

		array('label'=>'Logout', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest),

		array('label'=>'User Home', 'url'=>array('/user'), 'visible'=>!Yii::app()->user->isGuest)

		));

		

		//print_r($items);

		$controller=$this->controller;

		$action=$controller->action;

		

		foreach($items1 as $item)

		{

			if(isset($item['visible']) && !$item['visible'])

			continue;

			$item2=array();

			$item2['label']=$item['label'];

			if(is_array($item['url']))

			$item2['url']=$controller->createUrl($item['url'][0], (isset($item['url'][1]) ? $item['url'][1] : array()));

			else

			$item2['url']=$item['url'];

			$pattern=isset($item['pattern'])?$item['pattern']:$item['url'];

			$item2['active']=$this->isActive($pattern,$controller->uniqueID,$action->id);

			$items[]=$item2;

		}

		$this->render('mainMenu',array('items'=>$items));

	}


	/**

	 * Is the current menu item active?

	 * 

	 * @param $pattern

	 * @param $controllerID

	 * @param $actionID

	 * @return bool

	 */

	protected function isActive($pattern,$controllerID,$actionID)

	{

		if(!is_array($pattern) || !isset($pattern[0]))

		return false;


		$pattern[0]=trim($pattern[0],'/');

		if(strpos($pattern[0],'/')!==false)

		$matched=$pattern[0]===$controllerID.'/'.$actionID;

		else

		$matched=$pattern[0]===$controllerID;


		if($matched && count($pattern)>1)

		{

			foreach($pattern[1] as $name=>$value)

			{

				if(!isset($_GET[$name]) && $_GET[$name]!=$value)

				return false;

			}

			return true;

		}

		else

		return $matched;

	}

}



You can create self-referential relations with ease. Just define:




'parent'=>array(self::BELONGS_TO, 'Page', 'childOf'),



I think better method is with MPTT… checkout the nestedSet extension I am playing with the same thing too… jus trying to figure out now how to put several hierachies in 1 table…