options = $options;
}
/**
* Drop the "has children" class from items whose children are not in the list.
*
* WordPress stamps `menu-item-has-children` on before `wp_nav_menu_objects` runs, so
* anything that removes items on that filter - the plugin's own logged-in/logged-out
* visibility settings among them - can leave a parent claiming children it no longer
* has. The walker would then emit a submenu toggle whose aria-controls points at a
*
that is never rendered: a control that announces a collapsed submenu, resolves
* to nothing, and does nothing when activated.
*
* @since 4.7.4
* @access public
*
* @param array $elements Menu item objects.
* @param int $max_depth Maximum depth to walk.
* @param mixed ...$args Arguments passed through to the parent walker.
* @return string
*/
public function walk( $elements, $max_depth, ...$args ) {
$has_children = array();
foreach ( (array) $elements as $element ) {
if ( ! empty( $element->menu_item_parent ) ) {
$has_children[ intval( $element->menu_item_parent ) ] = true;
}
}
foreach ( (array) $elements as $element ) {
if ( empty( $element->classes ) || ! empty( $has_children[ intval( $element->ID ) ] ) ) {
continue;
}
$element->classes = array_diff( (array) $element->classes, array( 'menu-item-has-children' ) );
}
return parent::walk( $elements, $max_depth, ...$args );
}
/**
* Function to create element for menu items.
*
* @access public
* @version 4.0.0
*
* @param string/HTML $output
* @param object $item
* @param int $depth
* @param array $args
* @param int $id
*/
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$this->set_current_item( $item );
$classes = array();
if ( ! empty( $item->classes ) ) {
$classes = (array) $item->classes;
}
$rmp_menu_classes = $classes;
/** Add rmp menu classes as per item */
foreach ( $classes as $class ) {
switch ( $class ) {
case 'menu-item':
$rmp_menu_classes[] = 'rmp-menu-item';
break;
case 'current-menu-item':
$rmp_menu_classes[] = 'rmp-menu-current-item';
break;
case 'menu-item-has-children':
$rmp_menu_classes[] = 'rmp-menu-item-has-children';
break;
case 'current-menu-parent':
$rmp_menu_classes[] = 'rmp-menu-item-current-parent';
break;
case 'current-menu-ancestor':
$rmp_menu_classes[] = 'rmp-menu-item-current-ancestor';
break;
}
}
// Add top/sub level class as per item.
if ( 0 === intval( $item->menu_item_parent ) ) {
$rmp_menu_classes[] = 'rmp-menu-top-level-item';
$this->root_item_id = $item->ID;
} else {
$rmp_menu_classes[] = 'rmp-menu-sub-level-item';
}
/* Clear child class if we are at the final depth level */
if ( isset( $rmp_menu_classes ) ) {
$has_child = array_search( 'rmp-menu-item-has-children', $rmp_menu_classes, true );
if ( ( intval( $depth ) + 1 ) === intval( $this->options['menu_depth'] ) && false !== $has_child ) {
unset( $rmp_menu_classes[ $has_child ] );
}
}
$class_names = join( ' ', array_unique( $rmp_menu_classes ) );
/** Prepare classes for menu item. */
if ( ! empty( $class_names ) ) {
$class_names = sprintf( 'class="%s"', esc_attr( $class_names ) );
} else {
$class_names = '';
}
$class_names = apply_filters( 'rmp_nav_item_class', $class_names, $item );
// Start menu item and set classes & ID.
$output .= sprintf(
'