item_spacing ) && 'discard' === $args->item_spacing ) {
$t = '';
$n = '';
} else {
$t = "\t";
$n = "\n";
}
$indent = str_repeat( $t, $depth );
// Default class to add to the file.
$classes = array( 'dropdown-menu' );
/**
* Filters the CSS class(es) applied to a menu list element.
*
* @since WP 4.8.0
*
* @param array $classes The CSS classes that are applied to the menu `
` element.
* @param stdClass $args An object of `wp_nav_menu()` arguments.
* @param int $depth Depth of menu item. Used for padding.
*/
$class_names = join( ' ', apply_filters( 'nav_menu_submenu_css_class', $classes, $args, $depth ) );
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
/*
* The `.dropdown-menu` container needs to have a labelledby
* attribute which points to its trigger link.
*
* Form a string for the labelledby attribute from the latest
* link with an id that was added to the $output.
*/
$labelledby = '';
// Find all links with an id in the output.
preg_match_all( '/(/im', $output, $matches );
// With pointer at end of array check if we got an ID match.
if ( end( $matches[2] ) ) {
// Build a string to use as aria-labelledby.
$labelledby = 'aria-labelledby="' . esc_attr( end( $matches[2] ) ) . '"';
}
$mbl_drop_icon = get_theme_mod('mbl_drop_icon','fa fa-angle-down');
$output .= "{$n}{$indent}{$n}";
}
/**
* Starts the element output.
*
* @since WP 3.0.0
* @since WP 4.4.0 The {@see 'nav_menu_item_args'} filter was added.
*
* @see Walker_Nav_Menu::start_el()
*
* @param string $output Used to append additional content (passed by reference).
* @param WP_Post $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $id Current item ID.
*/
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
$t = '';
$n = '';
} else {
$t = "\t";
$n = "\n";
}
$indent = ( $depth ) ? str_repeat( $t, $depth ) : '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
/*
* Initialize some holder variables to store specially handled item
* wrappers and icons.
*/
$linkmod_classes = array();
$icon_classes = array();
/*
* Get an updated $classes array without linkmod or icon classes.
*
* NOTE: linkmod and icon class arrays are passed by reference and
* are maybe modified before being used later in this function.
*/
$classes = self::separate_linkmods_and_icons_from_classes( $classes, $linkmod_classes, $icon_classes, $depth );
// Join any icon classes plucked from $classes into a string.
$icon_class_string = join( ' ', $icon_classes );
/**
* Filters the arguments for a single nav menu item.
*
* @since WP 4.4.0
*
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param WP_Post $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
*/
$args = apply_filters( 'nav_menu_item_args', $args, $item, $depth );
// Add .dropdown or .active classes where they are needed.
if ( isset( $args->has_children ) && $args->has_children ) {
$classes[] = 'dropdown';
}
if ( in_array( 'current-menu-item', $classes, true ) || in_array( 'current-menu-parent', $classes, true ) ) {
$classes[] = 'active';
}
// Add some additional default classes to the item.
$classes[] = 'menu-item-' . $item->ID;
$classes[] = 'nav-item';
// Allow filtering the classes.
$classes = apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth );
// Form a string of classes in format: class="class_names".
$class_names = join( ' ', $classes );
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
/**
* Filters the ID applied to a menu item's list item element.
*
* @since WP 3.0.1
* @since WP 4.1.0 The `$depth` parameter was added.
*
* @param string $menu_id The ID that is applied to the menu item's `- ` element.
* @param WP_Post $item The current menu item.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $depth Depth of menu item. Used for padding.
*/
$id = apply_filters( 'nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args, $depth );
$id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
$output .= $indent . '
- ';
// Initialize array for holding the $atts for the link item.
$atts = array();
/*
* Set title from item to the $atts array - if title is empty then
* default to item title.
*/
if ( empty( $item->attr_title ) ) {
$atts['title'] = ! empty( $item->title ) ? strip_tags( $item->title ) : '';
} else {
$atts['title'] = $item->attr_title;
}
$atts['target'] = ! empty( $item->target ) ? $item->target : '';
$atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : '';
// If the item has children, add atts to the .
if ( isset( $args->has_children ) && $args->has_children && 0 === $depth && $args->depth > 1 ) {
$atts['href'] = '#';
$atts['data-toggle'] = 'dropdown';
$atts['aria-haspopup'] = 'true';
$atts['aria-expanded'] = 'false';
$atts['class'] = 'dropdown-toggle nav-link';
} else {
$atts['href'] = ! empty( $item->url ) ? $item->url : '';
$atts['class'] = 'nav-link';
}
// Allow filtering of the $atts array before using it.
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth );
// Build a string of the attributes.
$attributes = '';
foreach ( $atts as $attr => $value ) {
if ( ! empty( $value ) ) {
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
$attributes .= ' ' . $attr . '="' . $value . '"';
}
}
// Build HTML for the link item.
$item_output = $args->before;
$item_output .= '';
// Initialize $icon_html to store icon HTML if any.
$icon_html = '';
/*
* Append linkmod (e.g. .dropdown-header) and icon (e.g. .fa-.fa-link)
* classnames to the link item.
*/
if ( ! empty( $icon_class_string ) ) {
$icon_html = ' ';
}
/*
* If $linkmod_classes array contains any of our special modification
* classes then apply them to the .
*/
if ( ! empty( $linkmod_classes ) ) {
// Remove .dropdown-header from the .
if ( in_array( 'dropdown-header', $linkmod_classes, true ) ) {
$linkmod_classes = array_diff( $linkmod_classes, array( 'dropdown-header' ) );
// Remove link modification classes like .disabled from the .
} elseif ( in_array( 'disabled', $linkmod_classes, true ) ) {
$linkmod_classes = array_diff( $linkmod_classes, array( 'disabled' ) );
}
}
$item_output .= $args->link_before . $icon_html . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
$item_output .= '';
$item_output .= $args->after;
/**
* Filters a menu item's starting output.
*
* @since WP 3.0.0
*
* @param string $item_output The menu item's starting HTML output. Default '%2$s'.
* @param WP_Post $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param stdClass $args An object of wp_nav_menu() arguments.
*/
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
/**
* Traverse elements to create list from elements.
*
* Display one element if the element doesn't have any children otherwise, display the element and its children.
*
* @since WP 2.5.0
*
* @see Walker::display_element()
*
* @param WP_Post $element Data object.
* @param array $children_elements List of elements to continue traversing (passed by reference).
* @param int $max_depth Max depth to traverse.
* @param int $depth Depth of current element.
* @param array $args An array of arguments.
* @param string $output Used to append additional content (passed by reference).
* @return void
*/
public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
if ( ! $element ) {
return;
}
$id_field = $this->db_fields['id'];
// Display this element.
if ( is_object( $args[0] ) ) {
$args[0]->has_children = ! empty( $children_elements[ $element->$id_field ] );
}
parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
/**
* Menu Fallback
*
* If this function is assigned to the wp_nav_menu's fallback_cb variable
* and the wp_nav_menu function has no menu to show, this function will
* display nothing.
*
* @since WP 5.3.0
*/
public static function fallback( $args ) {
if ( current_user_can( 'edit_theme_options' ) ) {
/* Get Arguments. */
$container = $args['container'];
$container_id = $args['container_id'];
$container_class = $args['container_class'];
$menu_class = $args['menu_class'];
$menu_id = $args['menu_id'];
// Initialize var to store fallback html.
$fallback_output = '';
if ( $container ) {
$fallback_output = '<' . esc_attr( $container );
if ( $container_id ) {
$fallback_output .= ' id="' . esc_attr( $container_id ) . '"';
}
if ( $container_class ) {
$fallback_output .= ' class="' . sanitize_html_class( $container_class ) . '"';
}
$fallback_output .= '>';
}
$fallback_output .= '
' . esc_html__( 'Add a menu', 'artech' ) . '
';
$fallback_output .= '
';
if ( $container ) {
$fallback_output .= '' . esc_attr( $container ) . '>';
}
// Display the fallback html.
echo $fallback_output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
/**
* Pluck linkmod or icon classes from an array of classes.
*
* Supported linkmods: .disabled, .dropdown-header, .dropdown-divider, .sr-only.
* Supported iconsets: Font Awesome 4/5, Glypicons.
*
* Any of the above linkmod classes and icon classes will be removed
* from the passed array of classes. This is necessary so that we can
* separately use these classes to wrap the or generate the icon
* element respectively.
*
* @since WP 4.6.0
*
* @param array $classes An array of classes currently assigned to the item.
* @param array $linkmod_classes An array to hold linkmod classes.
* @param array $icon_classes An array to hold icon classes.
* @param int $depth Depth of menu item.
*
* @return array An array of classes with linkmod and icon classes plucked.
*/
private static function separate_linkmods_and_icons_from_classes( $classes, &$linkmod_classes, &$icon_classes, $depth ) {
// Separate linkmod classes.
$linkmod_classes = array_intersect( $classes, array( 'disabled', 'dropdown-header', 'dropdown-divider', 'sr-only' ) );
$classes = array_diff( $classes, $linkmod_classes );
// Separate icon classes.
$icon_classes = array_filter( $classes, function( $class ) {
return preg_match( '/^fa-(?:\S+)/i', $class ) || preg_match( '/^glyphicon-(?:\S+)/i', $class );
} );
$classes = array_diff( $classes, $icon_classes );
// Remove the default 'menu-item' classes that WordPress generates.
$classes = array_diff( $classes, array( 'menu-item', 'menu-item-type-post_type', 'menu-item-object-page' ) );
return $classes;
}
/**
* Remove linkmod attributes from elements.
*
* This method will take an array of attributes and remove linkmod specific
* attributes. This is necessary so that the attributes do not interfere
* with the output of the element. For example, .dropdown-header should
* not have a href attribute.
*
* @since WP 4.6.0
*
* @param array $atts An array of link attributes.
* @param array $linkmod_classes An array of linkmod classes.
*
* @return array An array of link attributes with linkmod attributes removed.
*/
private static function unset_linkmod_attributes( $atts, $linkmod_classes ) {
// Remove the href attribute if the item is a dropdown-header or divider.
if ( in_array( 'dropdown-header', $linkmod_classes, true ) || in_array( 'dropdown-divider', $linkmod_classes, true ) ) {
unset( $atts['href'] );
}
// Remove the href attribute if the item is disabled.
if ( in_array( 'disabled', $linkmod_classes, true ) ) {
unset( $atts['href'] );
}
// Return the array of $atts sans linkmod attributes.
return $atts;
}
} // End of wp_bootstrap_navwalker class.
} // End of function_exists().