Instantly share code, notes, and snippets.
Last active
March 31, 2018 16:31
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save tameemsafi/0723f3566bba14b6cff4dfc891dd18cf to your computer and use it in GitHub Desktop.
Custom wordpress navigation menu helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Navigation Menu helper | |
* | |
* Helper to get menu items | |
* | |
* @author Tameem Safi <[email protected]> | |
* @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 <[email protected]> | |
* @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 <[email protected]> | |
* @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 <[email protected]> | |
* @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 <[email protected]> | |
* @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 <[email protected]> | |
* @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