As I agree with @Tim Withers I start to solve problem from preparing current array:
function prepareMenu($array)
{
$return = array();
//1
krsort($array);
foreach ($array as $k => &$item)
{
if (is_numeric($item['Parent']))
{
$parent = $item['Parent'];
if (empty($array[$parent]['Childs']))
{
$array[$parent]['Childs'] = array();
}
//2
array_unshift($array[$parent]['Childs'],$item);
unset($array[$k]);
}
}
//3
ksort($array);
return $array;
}
Some explanation.
- This is a weak point as I assumed that order of your menu array will be constant. Assumed order is:
- top elements first
- after that children
- after that children of children
- so on..
- Here is a place where I add a child at beginning of array to save original order.
- Rollback to original order.
Then function to build menu:
function buildMenu($array)
{
echo '<ul>';
foreach ($array as $item)
{
echo '<li>';
echo $item['Name'];
if (!empty($item['Childs']))
{
buildMenu($item['Childs']);
}
echo '</li>';
}
echo '</ul>';
}
With this and proper array order, no matter how deep rabbit hole is - you have your tree.
Usage:
$menu = prepareMenu($menu);
buildMenu($menu);
Of course... There must be better way... :-P
EDIT:
For array (a little midification [next child]):
$menu = array(
array(
'Menu_IDX' => '1',
'Order' => '1',
'Name' => 'History',
'Parent' => '',
'Path' => 'History',
'Link' => '',
),
array
(
'Menu_IDX' => '2',
'Order' => '25',
'Name' => 'Review',
'Parent' => '',
'Path' => 'Review',
'Link' => 'Review',
),
array
(
'Menu_IDX' => '3',
'Order' => '35',
'Name' => 'Past Medical History',
'Parent' => '',
'Path' => 'Past Medical History',
'Link' => 'Past Medical History',
),
array
(
'Menu_IDX' => '4',
'Order' => '45',
'Name' => 'Item 1',
'Parent' => '0',
'Path' => 'Item 1',
'Link' => 'Item 1',
),
array
(
'Menu_IDX' => '5',
'Order' => '55',
'Name' => 'Item 2',
'Parent' => '0',
'Path' => 'Item 2',
'Link' => 'Item 2',
),
array
(
'Menu_IDX' => '6',
'Order' => '65',
'Name' => 'Item 3',
'Parent' => '0',
'Path' => 'Item 3',
'Link' => 'Item 3',
),
array
(
'Menu_IDX' => '7',
'Order' => '65',
'Name' => 'Item 31',
'Parent' => '5',
'Path' => 'Item 31',
'Link' => 'Item 31',
)
);
Output will be:
- History
- Item 1
- Item 2
- Item 3
- Review
- Past Medical History