+ // Items in items aren't allowed. Wrap nested items in 'default' groups.
+ if ( $parent->type == 'item' && $node->type == 'item' ) {
+ $default_id = $parent->id . '-default';
+ $default = $this->_get_node( $default_id );
+
+ // The default group is added here to allow groups that are
+ // added before standard menu items to render first.
+ if ( ! $default ) {
+ // Use _set_node because add_node can be overloaded.
+ // Make sure to specify default settings for all properties.
+ $this->_set_node( array(
+ 'id' => $default_id,
+ 'parent' => $parent->id,
+ 'type' => 'group',
+ 'children' => array(),
+ 'meta' => array(
+ 'class' => $group_class,
+ ),
+ 'title' => false,
+ 'href' => false,
+ ) );
+ $default = $this->_get_node( $default_id );
+ $parent->children[] = $default;
+ }
+ $parent = $default;
+
+ // Groups in groups aren't allowed. Add a special 'container' node.
+ // The container will invisibly wrap both groups.
+ } elseif ( $parent->type == 'group' && $node->type == 'group' ) {
+ $container_id = $parent->id . '-container';
+ $container = $this->_get_node( $container_id );
+
+ // We need to create a container for this group, life is sad.
+ if ( ! $container ) {
+ // Use _set_node because add_node can be overloaded.
+ // Make sure to specify default settings for all properties.
+ $this->_set_node( array(
+ 'id' => $container_id,
+ 'type' => 'container',
+ 'children' => array( $parent ),
+ 'parent' => false,
+ 'title' => false,
+ 'href' => false,
+ 'meta' => array(),
+ ) );
+
+ $container = $this->_get_node( $container_id );
+
+ // Link the container node if a grandparent node exists.
+ $grandparent = $this->_get_node( $parent->parent );
+
+ if ( $grandparent ) {
+ $container->parent = $grandparent->id;
+
+ $index = array_search( $parent, $grandparent->children, true );
+ if ( $index === false )
+ $grandparent->children[] = $container;
+ else
+ array_splice( $grandparent->children, $index, 1, array( $container ) );
+ }
+
+ $parent->parent = $container->id;
+ }
+
+ $parent = $container;
+ }