I have a flat array full of navigation menu items in WP. Each item knows its parent, but none of them seem to know if they have children.
Array
(
[0] => stdClass Object
(
[ID] => 22
[menu_item_parent] => 0
)
[1] => stdClass Object
(
[ID] => 108
[menu_item_parent] => 22
)
[2] => stdClass Object
(
[ID] => 117
[menu_item_parent] => 108
)
[3] => stdClass Object
(
[ID] => 118
[menu_item_parent] => 108
)
[4] => stdClass Object
(
[ID] => 106
[menu_item_parent] => 22
)
[5] => stdClass Object
(
[ID] => 119
[menu_item_parent] => 106
)
[6] => stdClass Object
(
[ID] => 120
[menu_item_parent] => 106
)
[7] => stdClass Object
(
[ID] => 23
[menu_item_parent] => 0
)
)
I've tried approaching it with conditional logic a few different ways (and each time hard-coding values which isn't ideal), but I keep coding myself into a mess. How can I iterate over the array to produce a result like this?
<ul>
<li>22
<ul class="child">
<li>108
<ul class="grandchild">
<li>117</li>
<li>118</li>
</ul>
</li>
<li>106
<ul class="grandchild">
<li>119</li>
<li>120</li>
</ul>
</li>
</ul>
</li>
<li>23</li>
</ul>
I ended up doing it like this:
<?php
$items = wp_get_nav_menu_items('primary'); // original flat array
foreach ($items as $item) {
$pages[$item->menu_item_parent][] = $item; // create new array
}
foreach ($pages[0] as $parent) {
if (isset($pages[$parent->ID])) { // if page has children
echo '<li>'.$parent->ID;
echo '<ul class="children">';
foreach ($pages[$parent->ID] as $child) {
if (isset($pages[$child->ID])) { // child has children
echo '<li>'.$child->ID;
echo '<ul class="grandchildren">';
foreach ($pages[$child->ID] as $grandchild) {
echo '<li>'.$grandchild->ID.'</li>';
}
echo '</ul></li>';
} else {
echo '<li>'.$child->ID.'</li>'; // child has no children
}
}
echo '</ul></li>';
} else { // page has no children
echo '<li>'.$parent->ID.'</li>';
}
}
?>