Source for file Menu.php
Documentation is available at Menu.php
// +----------------------------------------------------------------------+
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Ulf Wendel <ulf.wendel@phpdoc.de> |
// | Sebastian Bergmann <sb@sebastian-bergmann.de> |
// | Alexey Borzov <avb@php.net> |
// +----------------------------------------------------------------------+
// $Id: Menu.php,v 1.11 2004/02/21 15:54:09 avb Exp $
// Types of the menu entries, instead of former magic numbers
define('HTML_MENU_ENTRY_INACTIVE', 0 );
define('HTML_MENU_ENTRY_ACTIVE', 1 );
define('HTML_MENU_ENTRY_ACTIVEPATH', 2 );
define('HTML_MENU_ENTRY_PREVIOUS', 3 );
define('HTML_MENU_ENTRY_NEXT', 4 );
define('HTML_MENU_ENTRY_UPPER', 5 );
define('HTML_MENU_ENTRY_BREADCRUMB', 6 ); // like activepath, but for 'urhere' type
* Generates a HTML menu from a multidimensional hash.
* Special thanks to the original author: Alex Vorobiev <sasha@mathforum.com>.
* @version $Revision: 1.11 $
* @author Ulf Wendel <ulf.wendel@phpdoc.de>
* @author Alexey Borzov <avb@php.net>
* Menu structure as a multidimensional hash.
* Mapping from URL to menu path.
* Path to the current menu item.
* Menu type: tree, rows, you-are-here.
* URL Environment Variable
var $_urlEnvVar = 'PHP_SELF';
* The URL to use an URL for the current page, instead of the one normally
* taken from env. variables
* @see forceCurrentUrl(), getCurrentUrl()
* URL of the current page.
* @see getCurrentURL(), getPath()
* The renderer being used to output the menu
* @var object HTML_Menu_Renderer
* Initializes the menu, sets the type and menu structure.
* @param array menu structure
* @param string menu type
* @param string env. variable used to determine current URL
* @see setMenuType(), setMenu(), setURLEnvVar()
function HTML_Menu($menu = null , $type = 'tree', $urlEnvVar = 'PHP_SELF')
* Sets the menu structure.
* The menu structure is defined by a multidimensional hash. This is
* quite "dirty" but simple and easy to traverse. An example
* show the structure. To get the following menu:
* 11 - Projects => PHPDoc
* 'url' => '/projects/index.php',
* 2 => array( 'title' => 'Stuff', 'url' => '/stuff/index.php' )
* Note the index 'sub' and the nesting. Note also that 1, 11, 12, 2
* must be unique. The class uses them as ID's.
$this->_urlMap = array ();
* Sets the type of the menu.
* Available types are: 'tree', 'rows', 'urhere', 'prevnext', 'sitemap'.
* @param string type name
if (in_array($menuType, array ('tree', 'rows', 'urhere', 'prevnext', 'sitemap'))) {
$this->_menuType = $menuType;
$this->_menuType = 'tree';
* Sets the environment variable to use to get the current URL.
* @param string environment variable for current URL
$this->_urlEnvVar = $urlEnvVar;
* @param string Menu type: tree, urhere, rows, prevnext, sitemap
* @return string HTML of the menu
function get($menuType = '')
include_once 'HTML/Menu/DirectRenderer.php';
$this->render($renderer, $menuType);
return $renderer->toHtml ();
* @param string Menu type: tree, urhere, rows, prevnext, sitemap
function show($menuType = '')
print $this->get($menuType);
* @param object HTML_Menu_Renderer Renderer to use
* @param string type of the menu
function render(&$renderer, $menuType = '')
$this->_renderer = & $renderer;
// the renderer will throw an error if it is unable to process this menu type
$res = $this->_renderer->setMenuType($this->_menuType);
// storing to a class variable saves some recursion overhead
switch ($this->_menuType) {
$this->_renderRows ($this->_menu);
$this->_renderPrevNext ($this->_menu);
$this->_renderURHere ($this->_menu);
$this->_renderTree ($this->_menu);
* Finds the type for the node.
* @param string Node 'url' attribute
* @param int Level in the tree
* @return int Node type (one of HTML_MENU_ENTRY_* constants)
function _findNodeType ($nodeId, &$nodeUrl, $level)
$nodeUrl = $this->_urlPrefix . ((empty ($this->_urlPrefix) || '/' != $nodeUrl{0 })? $nodeUrl: substr($nodeUrl, 1 ));
if ($this->_currentUrl == $nodeUrl) {
// menu item that fits to this url - 'active' menu item
} elseif (isset ($this->_path[$level]) && $this->_path[$level] == $nodeId) {
// processed menu item is part of the path to the active menu item
// not selected, not a part of the path to the active menu item
* Renders the tree menu ('tree' and 'sitemap')
* @param array (sub)menu being rendered
* @param int current depth in the tree structure
function _renderTree ($menu, $level = 0 )
foreach ($menu as $node_id => $node) {
$type = $this->_findNodeType ($node_id, $node['url'], $level);
// follow the subtree if the active menu item is in it or if we want the full menu
$this->_renderTree ($node['sub'], $level + 1 );
* Renders the 'urhere' menu
* @param array (sub)menu being rendered
* @param int current depth in the tree structure
function _renderURHere ($menu, $level = 0 )
foreach ($menu as $node_id => $node) {
$type = $this->_findNodeType ($node_id, $node['url'], $level);
// follow the subtree if the active menu item is in it
if (isset ($node['sub'])) {
$this->_renderURHere ($node['sub'], $level + 1 );
* Renders the 'rows' menu
* @param array (sub)menu being rendered
* @param int current depth in the tree structure
function _renderRows ($menu, $level = 0 )
foreach ($menu as $node_id => $node) {
$type = $this->_findNodeType ($node_id, $node['url'], $level);
// follow the subtree if the active menu item is in it
// every (sub)menu has its own table
// go deeper if neccessary
$this->_renderRows ($submenu, $level + 1 );
* Renders the 'prevnext' menu
* @param array (sub)menu being rendered
* @param int current depth in the tree structure
* @param int flag indicating whether to finish processing
* (0 - continue, 1 - this is "next" node, 2 - stop)
function _renderPrevNext ($menu, $level = 0 , $flagStop = 0 )
static $last_node = array (), $up_node = array ();
foreach ($menu as $node_id => $node) {
// add this item to the menu and stop recursion - (next >>) node
$this->_renderer ->renderEntry ($node, $level, HTML_MENU_ENTRY_NEXT );
$type = $this->_findNodeType ($node_id, $node['url'], $level);
// WARNING: if there's no previous take the first menu entry - you might not like this rule!
if (0 == count($last_node)) {
list ($node_id, $last_node) = each($this->_menu );
// WARNING: if there's no up take the first menu entry - you might not like this rule!
if (0 == count($up_node)) {
list ($node_id, $up_node) = each($this->_menu );
// remember the last (<< prev) node
if (isset ($node['sub'])) {
$flagStop = $this->_renderPrevNext ($node['sub'], $level + 1 , $flagStop);
$this->_renderer ->finishRow ($level);
$this->_renderer ->finishMenu ($level);
* Returns the path of the current page in the menu 'tree'.
* @return array path to the selected menu item
* @see _buildUrlMap(), $_urlMap
$this->_buildUrlMap ($this->_menu , array ());
// If there is no match for the current URL, try to come up with
// the best approximation by shortening the url
while ($this->_currentUrl && !isset ($this->_urlMap [$this->_currentUrl ])) {
$this->_currentUrl = substr($this->_currentUrl , 0 , -1 );
return isset ($this->_urlMap [$this->_currentUrl ])? $this->_urlMap [$this->_currentUrl ]: array ();
* Builds the mappings from node url to the 'path' in the menu
* @param array (sub)menu being processed
* @param array path to the (sub)menu
* @return boolean true if the path to the current page was found, otherwise false.
* @see getPath(), $_urlMap
function _buildUrlMap ($menu, $path)
foreach ($menu as $nodeId => $node) {
$url = $this->_urlPrefix . ((empty ($this->_urlPrefix ) || '/' != $node['url']{0 })? $node['url']: substr($node['url'], 1 ));
$this->_urlMap [$url] = $path;
if ($url == $this->_currentUrl ) {
if (isset ($node['sub']) &&
$this->_buildUrlMap ($node['sub'], array_merge($path, array ($nodeId)))) {
* Returns the URL of the currently selected page.
* The returned string is used for all test against the URL's
* in the menu structure hash.
if (!empty ($this->_forcedUrl )) {
return $this->_forcedUrl;
} elseif (isset ($_SERVER[$this->_urlEnvVar ])) {
return $_SERVER[$this->_urlEnvVar ];
} elseif (isset ($GLOBALS[$this->_urlEnvVar ])) {
return $GLOBALS[$this->_urlEnvVar ];
* Forces the given URL to be "current"
* @param string Url to use
$this->_forcedUrl = $url;
* Sets the prefix for the URLs in the menu
if (('' != $prefix) && ('/' != substr($prefix, -1 ))) {
$this->_urlPrefix = $prefix;
Documentation generated on Mon, 11 Mar 2019 10:16:40 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|