<?php
/****************************************************************************
name: menu-bench.php
version: 2.1
copyright: (c) 2005/2006 Carsten Meier
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
contact: Carsten Meier
Under de Diek 19
D-26757 Borkum
Germany
homepage: http://www.internalscripts.de/menu-bench/
forum: http://www.internalscripts.de/forum/menu-bench/
e-mail: [cm at internalscripts dot de]
requirements: PHP >= 4.1.0
****************************************************************************/
///////////////////////////////////////////////////////////////////////////////
// nodes
// returns container-array corresponding to path or NULL on error
// $path - array of keys
// &$container - array of nodes
function &menubench_find_container($path, &$container)
{
foreach($path as $nodekey)
{
if(!isset($container[$nodekey]['children']))
return NULL;
$container = &$container[$nodekey]['children'];
}
return $container;
}
// returns node corresponding to path or NULL on error
// $path - array of keys
// &$container - array of nodes
function &menubench_find_node($path, &$container)
{
$key = array_pop($path);
$cont = &menubench_find_container($path, $container);
if($cont===NULL || !isset($cont[$key]))
return NULL;
return $cont[$key];
}
// returns node corresponding to path by using a node as a root-element.
// returns NULL on error.
// $path - array of keys
// &$node - root-node
function &menubench_find_node_ex($path, &$node)
{
foreach($path as $nodekey)
{
if(!isset($node['children'][$nodekey]))
return NULL;
$node = &$node['children'][$nodekey];
}
return $node;
}
///////////////////////////////////////////////////////////////////////////////
// items
// gets a single item as a formatted string
// $templ - template-array with the following elements:
// 'separator' => will be inserted to separate items
// $what-argument => format-string of item
// 'format_args' => Optional array that specifies the
// elements of the item. If not present, the following
// will be used: 'url', 'title', 'label'
// 'html_encode' => Optional string that specifies a
// charset. If present, the item-values will be encoded
// via htmlspecialchars(ENT_QUOTES, charset), otherwise
// not.
// $what - the key of the format-string to use
// $item
// $dosep - determines whether the item should be separated
function &menubench_get_item(&$templ, $what, &$item, &$dosep)
{
// query item-keys
if(isset($templ['format_args']))
$argkeys = &$templ['format_args'];
else
$argkeys = array('url', 'title', 'label');
// query item-values
$args = array();
if(isset($templ['html_encode']))
{
foreach($argkeys as $argkey)
$args[] = htmlspecialchars($item[$argkey],
ENT_QUOTES, $templ['html_encode']);
}
else
{
foreach($argkeys as $argkey)
$args[] = &$item[$argkey];
}
// format item
$str = vsprintf($templ[$what], $args);
if($str != '')
{
if($dosep)
$str = $templ['separator'].$str;
else
$dosep = true;
}
return $str;
}
// gets specified menu-items as a formatted string
// $curkey - the key of the current item in the $items-array
// $keys - array of item-keys to display
// &$items
// &$templ
// $curtemplkey - template-key of format-string to use for current item
// $prefix - prefix and postfix will only be inserted if items have been
// $postfix generated
function &menubench_get_menu_items($curkey, &$keys, &$items,
&$templ, $curtemplkey = 'current_item', $prefix = '', $postfix = '')
{
$str = '';
$dosep = false;
reset($keys);
while($ent = each($keys))
{
if(!isset($items[$ent[1]]))
continue;
if($curkey != $ent[1])
$w = 'item';
else
$w = $curtemplkey;
$str .= menubench_get_item(
$templ, $w, $items[$ent[1]], $dosep);
}
if($dosep)
$str = $prefix.$str.$postfix;
return $str;
}
///////////////////////////////////////////////////////////////////////////////
// navigation
// gets start/prev/next/end-links
// $curkey - the key of the current item in the $items-array
// &$items - array of nodes
// &$templ - template with following additional entries:
// 'prefix' - gets printed first
// 'postfix' - gets printed finally
// 'start' - format-strings for the corresponding link-types
// 'end'
// 'next'
// 'prev'
function &menubench_get_navigation($curkey, &$items, &$templ)
{
$str = '';
$dosep = false;
// start-link
reset($items);
if(($ent = each($items)) && $curkey != $ent[0])
{
// current item is not the first one
$str .= menubench_get_item($templ, 'start', $ent[1], $dosep);
// prev-link
while($newent = each($items))
{
if($curkey==$newent[0])
{
$str .= menubench_get_item(
$templ, 'prev', $ent[1], $dosep);
break;
}
$ent = $newent;
}
}
// next-link
if($ent = each($items))
{
// current item is not the last one
$str .= menubench_get_item($templ, 'next', $ent[1], $dosep);
// end-link
end($items);
$ent = each($items);
$str .= menubench_get_item($templ, 'end', $ent[1], $dosep);
}
if($str != '')
$str = $templ['prefix'].$str.$templ['postfix'];
return $str;
}
function menubench_navigation($curkey, &$items, &$templ)
{
print menubench_get_navigation($curkey, $items, $templ);
}
// gets start/prev/next/end-links of node specified by path
function &menubench_get_node_navigation($path, &$container, &$templ)
{
$key = array_pop($path);
$container = &menubench_find_container($path, $container);
$str = '';
if($container && array_key_exists($key, $container))
$str = &menubench_get_navigation($key, $container, $templ);
return $str;
}
// gets navigation-links of node specified by path.
// takes a node as root-element.
function &menubench_get_node_navigation_ex($path, &$node, &$templ)
{
if(isset($node['children']))
$str = menubench_get_node_navigation(
$path, $node['children'], $templ);
else
$str = '';
return $str;
}
///////////////////////////////////////////////////////////////////////////////
// menus
// gets a menu as a printable string
// $curkey - the key of the current item in the $items-array
// &$items - array of nodes
// &$templ - template with following additional entries:
// 'prefix' - gets printed first
// 'postfix' - gets printed finally
// 'item' - format-strings for the corresponding item-types
// 'current_item'
// 'parent_item'
// $curtemplkey - template-key of active element
function &menubench_get_menu(
$curkey, &$items, &$templ, $curtemplkey = 'current_item')
{
return menubench_get_menu_items($curkey, array_keys($items), $items,
$templ, $curtemplkey, $templ['prefix'], $templ['postfix']);
}
// as menubench_get_menu() but prints the menu instead of returning it
function menubench_menu(
$curkey, &$items, &$templ, $curtemplkey = 'current_item')
{
print menubench_get_menu($curkey, $items, $templ, $curtemplkey);
}
// gets a menu devided into groups as a printable string
// $curkey - the key of the current item in the $items-array
// &$items - array of nodes
// &$groups - array of item-key-arrays
// &$grouptitles - array of group-titles
// &$templ - template with following additional entries:
// 'prefix' - prefix if group-title is NULL
// 'postfix' - postfix if group-title is NULL
// 'group_prefix' - prefix and postfix as format-strings if group-title
// 'group_postfix' is non-null (group-title as %1)
// 'group_separator' - separator between groups
// 'item' - format-strings for the corresponding item-types
// 'current_item'
// 'parent_item'
// $curtemplkey - template-key of active element
function &menubench_get_group_menu(
$curkey, &$items, &$groups, $grouptitles,
&$templ, $curtemplkey = 'current_item')
{
$str = '';
$dosep = false;
foreach($groups as $groupkey => $group)
{
if(isset($grouptitles[$groupkey]))
{
if(isset($templ['html_encode']))
$grouptitle = htmlspecialchars(
$grouptitles[$groupkey],
ENT_QUOTES,
$templ['html_encode']);
else
$grouptitle = $grouptitles[$groupkey];
$prefix = sprintf($templ['group_prefix'], $grouptitle);
$postfix = sprintf(
$templ['group_postfix'], $grouptitle);
}
else
{
$prefix = $templ['prefix'];
$postfix = $templ['postfix'];
}
$groupstr = &menubench_get_menu_items($curkey, $group, $items,
$templ, $curtemplkey, $prefix, $postfix);
if($groupstr != '')
{
if($dosep)
$str .= $templ['group_separator'];
else
$dosep = true;
$str .= $groupstr;
}
}
return $str;
}
// gets the menu of a given node as a printable string. Uses a node as a
// starting point.
// $path - array of keys
// $menupath - array of keys for menu
// &$node
// &$templ - template with following additional entries:
// 'prefix' - prefix if group-title is NULL
// 'postfix' - postfix if group-title is NULL
// 'group_prefix' - prefix and postfix as format-strings if group-title
// 'group_postfix' is non-null (group-title as %1)
// 'group_separator' - separator between groups
// 'item' - format-strings for the corresponding item-types
// 'current_item'
// 'parent_item'
function &menubench_get_node_menu_ex($path, $menupath, &$node, &$templ)
{
// determine node and level
reset($path);
reset($menupath);
$disjointed = false;
while($menucomp = each($menupath))
{
if(isset($node['children'][$menucomp[1]]))
$node = &$node['children'][$menucomp[1]];
else
return '';
if(!$disjointed)
{
$comp = each($path);
if(!$comp || $comp[1] != $menucomp[1])
$disjointed = true;
}
}
if(!isset($node['children']))
return '';
if($disjointed)
$acttemplkey = 'item';
else if(($comp = each($path)) && !each($path))
$acttemplkey = 'current_item';
else
$acttemplkey = 'parent_item';
// generate menu
if(isset($templ['group_prefix']) && !empty($node['groups']))
return menubench_get_group_menu(
$comp[1], $node['children'],
$node['groups'], $node['group_labels'],
$templ, $acttemplkey);
else
return menubench_get_menu(
$comp[1], $node['children'], $templ, $acttemplkey);
}
// gets the menu of a given node as a printable string.
// like menubench_get_node_menu_ex() but takes a container as root-element.
function &menubench_get_node_menu($path, $menupath, &$container, &$templ)
{
$node = array('children' => &$container);
return menubench_get_node_menu_ex($path, $menupath, $node, $templ);
}
///////////////////////////////////////////////////////////////////////////////
// path-navigation
// returns path-navigation as a string
// $path - array of keys
// &$node - root-node
// &$templ - array with the following entries:
// 'prefix' - gets printed first
// 'postfix' - gets printed finally
// 'separator' - separates items
// 'current_item' - format-strings for the corresponding item-types
// 'parent_item' (as documented at menubench_get_item)
function &menubench_get_path_navigation_ex($path, &$node, &$templ)
{
$str = '';
$dosep = false;
reset($path);
$comp = each($path);
while($comp)
{
if(!isset($node['children'][$comp[1]]))
break;
$node = &$node['children'][$comp[1]];
$comp = each($path);
if($comp)
$w = 'parent_item';
else
$w = 'current_item';
$str .= menubench_get_item($templ, $w, $node, $dosep);
}
if($str != '')
$str = $templ['prefix'].$str.$templ['postfix'];
return $str;
}
// as menubench_get_path_navigation_ex() but takes a container as root-element.
function &menubench_get_path_navigation($path, &$container, &$templ)
{
$node = array('children' => &$container);
return menubench_get_path_navigation_ex($path, $node, $templ);
}
?>