I've been coding on experts exchange, testing myself. Here's some relevant code for one of the answers.
They're classes that have been used to generate hierarchical menus.
<?php /** * @package menu * @author John Kawakami * @link http://www.slaptech.net Developed by The Slaptech Collective * @copyright 2006 Public Domain * @version $Id: Menu.class.php 97 2006-07-27 10:43:40Z johnk $ * * Library to help create hierarchical menus. * Use MenuRenderer to display the menus. * * * $menuBar = new Menu('MenuBar'); * $fileMenu = $menuBar->addMenu( 'File' ); * $fileMenu->addUrl( 'Open', '/admin/foo.php' ); * $fileMenu->addUrl( 'Save', '/admin/bar.php' ); * $fileMenu->addDivider(); * $fileMenu->addUrl( 'Close', '/admin/baz.php' ); * */ include_once('ACL.class.php'); class Menu { var $acl; var $menu; var $menuHash; //fixme - combine these two structures into one var $name; var $description; var $icon; var $url; var $highlight; function Menu( &$acl, $name, $description='', $icon='', $url='' ) { $this->acl =& $acl; $this->menu = array(); $this->name =& $name; $this->description =& $description; $this->icon =& $icon; $this->url =& $url; $this->highlight = false; } function addObject( &$obj ) { array_push( $this->menu, &$obj ); } function addNamedObject( $name, &$obj ) { $this->menuHash[$name] =& $obj; $this->addObject( &$obj ); } /** * Utility function. */ function &addMenu( &$acl, $name, $description='', $icon='', $url='' ) { $new = new Menu( &$acl, $name, $description, $icon, $url ); $this->addObject( $new ); return $new; } function &getNamedObject( $name ) { return $this->menuHash[$name]; } function &addUrl( &$acl, $name, $url, $description='', $popup='' ) { $new = new UrlMenuItem( &$acl, $name, $url, $description, $popup ); $this->addObject( $new ); return $new; } function &addDivider() { $new = new DividerMenuItem(); $this->addObject( $new ); return $new; } function select( $name ) { for( $i=0; $i < count($this->menu); $i++ ) { if ($this->menu[$i]->name==$name) { return $this->menu[$i]; } } } function rewind() { reset($this->menu); } function &next() { // check the acl to see if this user can see the next item - fixme list( $index, $obj ) = each( $this->menu ); return $obj; } function disable() { $this->enabled = false; } function enable() { $this->enabled = true; } function highlight() { $this->highlight = true; } } class UrlMenuItem extends Menu { var $name; var $url; var $description; var $popup; function &UrlMenuItem( &$acl, $name, $url, $description='', $popup='' ) { $this->acl =& $acl; $this->name =& $name; $this->url =& $url; $this->description =& $description; $this->popup =& $popup; return $this; } } class DividerMenuItem extends Menu { function DividerMenuItem() { $this->name = 'divider'; } } ?>The menus are rendered via another class:<?php /** * @package menu * @author John Kawakami * @link http://www.slaptech.net Developed by The Slaptech Collective * @copyright 2006 Public Domain * @version $Id: MenuRenderer.class.php 92 2006-07-27 09:13:10Z johnk $ * * Rendering classes for menus. These are kind of like "templates" * for menus, except they can render hierarchies, portions of menus, * etc. There's HTML code in here. Yuk. */ /** * Rendering interface. Each renderer must implement the * url, divider, and menu methods. The menu() method is the heart * of the renderer. */ class MenuRenderer { function MenuRenderer() {} function divider() {} function url() {} function menu() {} function item( $obj ) { return $obj->name; } } /** * Renders a menu as an html unordered list (UL). */ class HtmlMenuRenderer extends MenuRenderer { function HtmlMenuRenderer() {} function menu( &$menu, $indent=0 ) { $t = str_repeat( ' ', $indent ); $m =& $menu; $m->rewind(); if ($m->name != '@') $output .= "$t"; if ($m->name != '@') { if ($m->url) $output .= "url'>"; if ($m->icon) { $output .= " \n"; return $output; } function divider( &$obj, $indent=0 ) { $t = str_repeat( ' ', $indent ); return "$ticon' border='0' />"; $output .= "
"; } $output .= $m->name."\n"; if ($m->url) $output .= ''; } $output .= "$t\n"; while( $obj =& $m->next() ) { $class = strtolower(get_class($obj)); // echo "$class
\n"; if ($m->name != '@') $output .= "$t
"; switch( $class ) { case 'apmenu': case 'menu': $output .= $this->menu( $obj, $indent+4 ); break; case 'urlmenuitem': $output .= $this->url( $obj, $indent+4 ); break; case 'dividermenuitem': $output .= $this->divider( $obj, $indent+4 ); break; default: $output .= $this->item( $obj, $indent+4 ); break; } } $output .= "$t----------- \n"; } function url( &$obj, $indent=0 ) { $t = str_repeat( ' ', $indent ); return "$turl'>$obj->name \n"; } }