Seu código só vai gerar menu de dois níveis, se você precisar passar por qualquer nível que quiser, acho que você precisa usar recursão.
Aqui está um exemplo baseado em sua estrutura de banco de dados e exemplos. No exemplo vamos gerar um menu em diferentes níveis, os rótulos em inglês são usados para nomes de itens de menu.
<?php
$db = new PDO('mysql:host=localhost;dbname=testdb', 'root', '');
function drawMenu($db, $parent, $level = null){
$m = $db->prepare(" SELECT * FROM
administrator_menu, administrator_menu_description
where administrator_menu.id = administrator_menu_description.id
and language_id = 2
and parent_id = $parent");
$m->execute();
foreach ($m->fetchAll() as $menu_row) {
$m = $db->prepare("SELECT count(*) FROM administrator_menu where parent_id = $menu_row[id]");
$m->execute();
// The item is parent, so do recursion again
if($m->fetchAll()[0][0] !== '0' && $level !== 0){
echo "<li>" . $menu_row['label']."<ul>";
drawMenu($db, $menu_row[0], $level - 1);
echo "</ul></li>";
}else{ // The item is a leaf or we reach the end level, i.e. base case, so do print the item label
echo "<li>" . $menu_row['label'] . "</li>";
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<?php
echo "<div> <ul>";
drawMenu($db, 0, null); // all levels
echo "</ul></div>";
echo "--------------------------------------------------------";
echo "<div> <ul>";
drawMenu($db, 0, 0); // level 0
echo "</ul></div>";
echo "--------------------------------------------------------";
echo "<div> <ul>";
drawMenu($db, 0, 1); // level 1
echo "</ul></div>";
echo "--------------------------------------------------------";
echo "<div> <ul>";
drawMenu($db, 0, 2); // level 2
echo "</ul></div>";
?>
</body>
</html>
Para desenhar todos os níveis:
echo "<div> <ul>";
drawMenu($db, 0, null); // all levels
echo "</ul></div>";
O
drawMenu
função funciona da seguinte forma:- Primeiro passamos um
$db
objeto para fazer consultas ao banco de dados,$parent
com a qual a árvore começará e$level
para o nível da árvore. - A função começará selecionando o filho de determinado
$parent
e entre em loop para cada umforeach ($m->fetchAll() as $menu_row) {...}
. -
No loop temos dois casos:
-
O item é uma folha, ou seja, não é pai de outros itens, ou chegamos ao nível final da árvore. Este caso é chamado de caso base , em que a recursão irá parar e retornar um valorecho "<li>" . $menu_row['label'] . "</li>";
-
O item é pai, neste caso chamamos dedrawMenu
funcione novamente com o id do item$menu_row[0]
como pai e$level - 1
para certificar-se de parar quando chegar ao final dos níveis.
-
Teste o código e altere-o para atender às suas necessidades.