Skip to content

Instantly share code, notes, and snippets.

@stamat
Last active June 16, 2024 11:42
Show Gist options
  • Save stamat/1d535f0dbf2e8f8237e1ec0703d57577 to your computer and use it in GitHub Desktop.
Save stamat/1d535f0dbf2e8f8237e1ec0703d57577 to your computer and use it in GitHub Desktop.
WordPress submenu tree generator from a list of menu items 🤯
// usage `get_menu_tree('your_menu');`
// PHP 5,7 and 8
function get_menu($menu_name) {
if (( $locations = get_nav_menu_locations()) && isset( $locations[$menu_name])) {
return wp_get_nav_menu_items($locations[$menu_name]);
}
return null;
}
function build_tree_from_index($level, $index, $carry = null) {
foreach( $level as $key => $value ) {
if (!empty($carry) && $carry['parent_id'] === $key) {
$level->offsetSet($key, $carry->getArrayCopy());
$carry = null;
}
if ($index->offsetExists($value['parent_id'])) {
if ($index->offsetExists($key)) $index->offsetUnset($key);
$carry = $value->getArrayCopy();
}
if ($value['sub_items']->count()) {
build_tree_from_index($value['sub_items'], $index, $carry);
} else {
if ($index->offsetExists($value['id']) && !empty($value['parent_id'])) {
$index->offsetUnset($value['id']);
}
}
}
}
function index_menu_items($menu, $menu_index) {
foreach( $menu as $menu_item ) {
$parent_id = $menu_item->menu_item_parent;
$has_parent = !empty($parent_id);
$id = $menu_item->object_id;
$value = new ArrayObject(array(
'id' => $id,
'title' => $menu_item->title,
'url' => $menu_item->url,
'parent_id' => $parent_id,
'sub_items' => new ArrayObject(array())
));
if ($has_parent) {
if ($menu_index->offsetExists($parent_id)) {
$menu_index[$parent_id]['sub_items']->offsetSet($id, $value);
}
}
$menu_index->offsetSet($id, $value);
}
}
function get_menu_tree($menu_name) {
$menu = get_menu($menu_name);
$menu_index = new ArrayObject(array());
index_menu_items($menu, $menu_index);
build_tree_from_index($menu_index, $menu_index);
return $menu_index;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment