How about following approach?
Have a class which generated items array that can be directly passed to CMenu.
Here, getMenuItemsRecursive method scans table and generates a complete array which can be passed to CMenu directly.
getMenuItems method can be programmed to include various logics and also have cache implemented for performance boost.
[PHP]
class MyMenu extends CActiveRecord
{
public $id;
public $title;
public $parentId;
public $url;
public function tableName()
{
return 'test.tbl_menu';
}
public static function model($className = __CLASS__)
{
return parent::model($className);
}
public function relations()
{
return array(
'childMenu' => array(self::HAS_MANY, 'MyMenu', 'parentId'),
);
}
public function getMenuItems()
{
$result = array(
'label' => $this->title,
'url' => $this->url,
);
if(isset($this->childMenu))
{
$childrens = array();
foreach($this->childMenu as $cm)
{
$childrens[] = $cm->getMenuItems();
}
if(!empty($childrens))
{
$result['items'] = $childrens;
}
}
return $result;
}
public static function getMenuItemsRecursive()
{
$result = array();
$models = self::model()->findAllByAttributes(array('parentId' => 0));
if($models)
{
foreach($models as $menu)
{
$result[] = $menu->getMenuItems();
}
}
return $result;
}
public static function doTest()
{
$menuItems = self::getMenuItemsRecursive();
echo '<pre>';
print_r($menuItems);
echo '</pre>';
exit;
}
}
[/PHP]
Below is dump of table I used as reference.
-- ----------------------------
-- Table structure for `tbl_menu`
-- ----------------------------
DROP TABLE IF EXISTS `tbl_menu`;
CREATE TABLE `tbl_menu` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`parentId` int(11) unsigned NOT NULL DEFAULT '0',
`url` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of tbl_menu
-- ----------------------------
INSERT INTO `tbl_menu` VALUES ('1', 'Home', '0', '/home');
INSERT INTO `tbl_menu` VALUES ('2', 'About', '0', '/about');
INSERT INTO `tbl_menu` VALUES ('3', 'Contact', '2', '/contact');
INSERT INTO `tbl_menu` VALUES ('4', 'Services', '0', '/services');
INSERT INTO `tbl_menu` VALUES ('5', 'Programming', '4', '/programming');
INSERT INTO `tbl_menu` VALUES ('6', 'Designing', '4', '/designing');
INSERT INTO `tbl_menu` VALUES ('7', 'PHP', '5', '/php');
INSERT INTO `tbl_menu` VALUES ('8', 'Java', '5', '/java');