static function MenuReduce_Expand($menu, $expand_level, $curr_title_key, $top_level) { $result_menu = array(); $submenu = array(); //if $top_level is set, we need to take it into consideration $expand_level = max($expand_level, $top_level); //titles higher than the $expand_level $good_titles = array(); foreach ($menu as $title_key => $level) { if ($level < $expand_level) { $good_titles[$title_key] = $level; } } if (isset($menu[$curr_title_key])) { $curr_level = $menu[$curr_title_key]; $good_titles[$curr_title_key] = $menu[$curr_title_key]; //titles below selected // cannot use $submenu because $foundTitle may require titles above the $submenu threshold $foundTitle = false; foreach ($menu as $title_key => $level) { if ($title_key == $curr_title_key) { $foundTitle = true; continue; } if (!$foundTitle) { continue; } if ($curr_level + 1 == $level) { $good_titles[$title_key] = $level; } elseif ($curr_level < $level) { continue; } else { break; } } //reduce the menu to the current group $submenu = gpOutput::MenuReduce_Group($menu, $curr_title_key, $expand_level, $curr_level); //message('group: ('.count($submenu).') '.showArray($submenu)); // titles even-with selected title within group $even_temp = array(); $even_group = false; foreach ($submenu as $title_key => $level) { if ($title_key == $curr_title_key) { $even_group = true; $good_titles = $good_titles + $even_temp; continue; } if ($level < $curr_level) { if ($even_group) { $even_group = false; //done } else { $even_temp = array(); //reset } } if ($level == $curr_level) { if ($even_group) { $good_titles[$title_key] = $level; } else { $even_temp[$title_key] = $level; } } } // titles above selected title, deeper than $expand_level, and within the group gpOutput::MenuReduce_Sub($good_titles, $submenu, $curr_title_key, $expand_level, $curr_level); gpOutput::MenuReduce_Sub($good_titles, array_reverse($submenu), $curr_title_key, $expand_level, $curr_level); } //rebuild $good_titles in order // array_intersect_assoc() would be useful here, it's php4.3+ and there's no indication if the order of the first argument is preserved foreach ($menu as $title => $level) { if (isset($good_titles[$title])) { $result_menu[$title] = $level; } } return $result_menu; }