Skip to content

Instantly share code, notes, and snippets.

@tameemsafi
Last active March 31, 2018 16:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tameemsafi/0723f3566bba14b6cff4dfc891dd18cf to your computer and use it in GitHub Desktop.
Save tameemsafi/0723f3566bba14b6cff4dfc891dd18cf to your computer and use it in GitHub Desktop.
Custom wordpress navigation menu helper
<?php
/**
* Navigation Menu helper
*
* Helper to get menu items
*
* @author Tameem Safi <tameem@safi.me.uk>
* @version 1.0.0
*/
class WP_Nav_Menu_Helper {
/**
* Creates an array based on the wordpress navigation menu location
*
* @param String $location Location of the navigation menu
* @return Array|false The menu items as an array or false if not found
*
* @author Tameem Safi <tameem@safi.me.uk>
* @since 1.0.0
*/
public static function get_nav_menu_array( $location = false ) {
$menu_object = self::get_menu_by_location( $location );
if( !empty( $menu_object ) ) {
$nav_menu_items = wp_get_nav_menu_items( $menu_object );
if( !empty( $nav_menu_items ) ) {
$nav_items = [];
foreach($nav_menu_items as $item) {
if( absint( $item->menu_item_parent ) !== 0 ) continue;
$nav_items[] = self::filter_nav_menu_item( $item, $nav_menu_items );
}
return $nav_items;
}
}
return false;
}
/**
* Creates an array for the current nav menu item
*
* @param String $item Current nav menu item
* @param Array $nav_menu_items All nav menu items
* @return Array nav menu item array containing all its children
*
* @author Tameem Safi <tameem@safi.me.uk>
* @since 1.0.0
*/
public static function filter_nav_menu_item( $item, $nav_menu_items ) {
global $wp_query, $wp_rewrite;
$front_page_url = home_url();
$front_page_id = (int) get_option( 'page_on_front' );
$queried_object_id = (int) $wp_query->queried_object_id;
$current = false;
if( absint( $item->object_id ) == $queried_object_id ) {
$current = true;
}
if( 'custom' == $item->object && isset( $_SERVER['HTTP_HOST'] ) ) {
$_root_relative_current = untrailingslashit( $_SERVER['REQUEST_URI'] );
if ( is_customize_preview() ) {
$_root_relative_current = strtok( untrailingslashit( $_SERVER['REQUEST_URI'] ), '?' );
}
$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_root_relative_current );
$raw_item_url = strpos( $item->url, '#' ) ? substr( $item->url, 0, strpos( $item->url, '#' ) ) : $item->url;
$item_url = set_url_scheme( untrailingslashit( $raw_item_url ) );
$_indexless_current = untrailingslashit( preg_replace( '/' . preg_quote( $wp_rewrite->index, '/' ) . '$/', '', $current_url ) );
if ( $raw_item_url && in_array( $item_url, array( $current_url, $_indexless_current, $_root_relative_current ) ) ) {
$current = true;
}
if( $item_url == $front_page_url && is_front_page() ) {
$current = true;
}
}
$children = self::get_all_menu_item_children( $item, $nav_menu_items );
return [
'id' => $item->ID,
'title' => $item->title,
'classes' => $item->classes,
'xfn'=> $item->xfn,
'url' => $item->url,
'attr_title' => $item->attr_title,
'target' => $item->target,
'current' => $current,
'parent_of_current' => self::check_if_nav_item_or_its_children_is_current_page( $children ),
'children' => $children,
];
}
/**
* Get all the children of the current item
*
* @param String $item Current nav menu item
* @param Array $nav_menu_items All nav menu items
* @return Array all children of current item
*
* @author Tameem Safi <tameem@safi.me.uk>
* @since 1.0.0
*/
public static function get_all_menu_item_children( $current_item, $nav_menu_items ) {
$children = [];
foreach( $nav_menu_items as $item ) {
if( absint( $item->menu_item_parent ) === absint( $current_item->ID ) ) {
$children[] = self::filter_nav_menu_item( $item, $nav_menu_items );
}
}
return $children;
}
/**
* Check if any of the items or its children is the current page
*
* @param String $nav_items Current nav menu item
* @returns Boolean which indicates wether the current page is amongst one of the children
*
* @author Tameem Safi <tameem@safi.me.uk>
* @since 1.0.0
*/
public static function check_if_nav_item_or_its_children_is_current_page( $nav_items ) {
if( empty( $nav_items ) ) return false;
foreach($nav_items as $item) {
if( !empty( $item['current'] ) || !empty( $item['parent_of_current'] ) ) return true;
if( !empty( $item['children'] ) ) {
$is_current_page = self::check_if_nav_item_or_its_children_is_current_page( $item );
}
}
return false;
}
/**
* Gets a menu object based on location
*
* @param String $location The location of the menu
* @return WP_Term|false Returns the wordpress term object or false if not found
*
* @author Tameem Safi <tameem@safi.me.uk>
* @since 1.0.0
*/
public static function get_menu_by_location( $location = false ) {
if( !empty( $location ) ) {
$theme_menu_locations = get_nav_menu_locations();
// Check to make sure navigation location exists
if(
!empty( $theme_menu_locations ) &&
is_array( $theme_menu_locations ) &&
isset( $theme_menu_locations[$location] )
) {
$menu_object = get_term( $theme_menu_locations[$location], 'nav_menu' );
if( !empty( $menu_object ) ) {
return $menu_object;
}
}
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment