Location: PHPKode > scripts > Accessible nested DHTML menus > accessible-nested-dhtml-menus/MenuNode.php
 <?php
 /*
 MenuNode class - Provides methods for building and outputting a menu.
 An instance of this contains other instances for subnodes.
 See examples for usage.
 
 Author: Mick Sear
 eCreate, July 2005
 License: LGPL - This means you can use it in your apps (commercial as well as 
 non-commercial, but this message must be kept intact, source code must be provided to 
 clients, and changes to the code must be marked as by yourselves.
 */
 
 
 class MenuNode{
   
   var $elements = array();   //A multi-dimensional array of elements
   var $count = 0;           //The current position in the array
        
   /**
    * @param $title - Link text
    * @param $url - underlying url
    * @param $here - boolean - is this item marked as the current nav position?
    * Key to this class is the fact that nodes are passed by reference
    * This means that we can add nodes in any order.
    */
   function addNode(&$menu, $title='', $url=''){
      $this->elements[]= array('node' => &$menu->elements, 'title'=>$title, 'url'=>$url);
   }  
    
    /**
     * @param $title - the string that is displayed
     * @param $url - the underlying link
     * This method could easily be extended to provide things like 
     * custom link colours, images, target, etc. to the <li>.
     */
    /*function add($title, $url){
        $this->elements[] = array('title'=>$title, 'url'=>$url);
    }*/
   
    /**
     * returns the menu html.  
     */
   function display(){
      $out .= $this->recurse($this->elements);     
      $out = str_replace("<li><ul></ul></li>", "", $out);//Lose empty nodes
      return $out;
   }
   
    /**
     * Loops through the array that's been built up and outputs semantic, structural markup
     * This is recursive, so it will display all nested nodes as nested <ul>'s
     */
   function recurse($fragment){
      
      $out .= "<ul>";
      $this->count++;
        
      if (is_array($fragment)){
            
            $count = count($fragment);
            
            for($i=0;$i<$count;$i++){
                //Persist the current state of the menu - this is carried over in the URL.
                $css = "";
                if ($_GET['current'] == "menu".$this->count){
                    $css = " class='show' ";
                } 
                $out .= "<li id='menu".$this->count."'".$css.">";
          
                if ($fragment[$i]['url'] != ""){
                    //Ternary statement to determine if there are already GET params in the URL
                    (strpos($fragment[$i]['url'], "?"))?$sep="&":$sep="?";
                    $out .= "<a href='".$fragment[$i]['url'].$sep."current=menu".$this->count."' title='".$fragment[$i]['title']."'>".$fragment[$i]['title']."</a>\n";
                } else if (isset($fragment[$i]['title'])){
                    $out .= "<div class='pad'>".$fragment[$i]['title']."</div>\n";
                }

                if (isset($fragment[$i]['node'])){
                    $out .= $this->recurse($fragment[$i]['node']);
                }          
                
                $out .= "</li>";

         }              
            
      }
      $out .= "</ul>";
      
      return $out;
   }  
   
   /*
   This javascript needs to go in the document head, so there's a separate method to return it here.
   */   
   function getJavascript(){
       $javascript = "<script language='javascript'>
       var menuCount = ".$this->count.";
       //Persist current menu
       var Current = '".$_GET['current']."';           
       </script>";
       return $javascript;
   }   
 }
?>
Return current item: Accessible nested DHTML menus