I'm writing a wordpress plugin that makes changes to the admin menu. To add some context: The wordpress global $menu
is a multidimensional array. Each array in $menu
represents a menu item, with the title, url, css classes etc at specific indexes in the array. the oa_custom_menu
option is a similarly structured multidimensional array, but each menu item may have additional indexes in its array to store things like wether the menu item should be hidden or not.
the oa_custom_menu
array is only updated when changes are made in my custom admin page. The $menu
array may have changed since the last time this happened (e.g. new plugins or themes being activated and adding menu items), so I need to check for any added or removed items in the array.
index 2 in both menu arrays are the URL and the only thing that will consistently be unique. $custom_menu_item[7]
is a bool that indicates wether the item should be hidden or not, so we ignore these items if they are hidden..
I hope that all makes sense, I'm not the best at explaining things!
The code I have works perfectly well, it just seems like too many foreach loops to me, but I can not for the life of me figure out a better way to do it. Am I right?
public function compare_menu_arrays() {
global $menu;
$custom_menu = get_option('oa_custom_menu') ? get_option('oa_custom_menu') : $menu;
$menu_sort_keys = array();
$custom_menu_sort_keys = array();
foreach ( $menu as $menu_item ) {
$menu_sort_keys[] = $menu_item[2];
}
foreach ( $custom_menu as $custom_menu_item ) {
if ( empty($custom_menu_item[7]) ) {
$custom_menu_sort_keys[] = $custom_menu_item[2];
}
}
$new_menu_items = array_diff( $menu_sort_keys, $custom_menu_sort_keys );
$removed_menu_items = array_diff( $custom_menu_sort_keys, $menu_sort_keys );
/*
* add any new $menu items to our $custom_menu
*/
if ( !empty($new_menu_items) ) {
foreach ( $menu as $menu_item ) {
if ( in_array( $menu_item[2], $new_menu_items ) ) {
$custom_menu[] = $menu_item;
}
}
}
/*
* remove any missing $menu items from our $custom_menu
*/
if ( !empty($removed_menu_items) ) {
foreach ( $custom_menu as $index => $custom_menu_item ) {
if ( in_array( $custom_menu_item[2], $removed_menu_items ) ) {
unset( $custom_menu[$index] );
}
}
}
}