Skip to content


php: Menu Classes

Recently I’ve been working on my own framework (we’ve all done it i’m sure) and part of this was a menu handling system.

The basis really is simple, we have a menu item which really is just link and text. That menu item could have children, could be active and/or be selected.

In this case Selected is the currently menu item, which is also Active, and all it’s parents in the chain upwards are also active.

We also have a menu controller which makes it easier to add to the menus.

class menuHandler {
    public $menus=array();
    public function NewMenu() {
        $k = time();
        $this->menus[$k] = new menu_class();
        return $k;
    }
    public function AddMenu($key,menu_class $menu) {
        if (!isset($this->menus[$key])) {
            $this->menus[$key] = $menu;
        }
        return $this;
    }
    public function ItemCount($menuKey) {
        $menu = $this->menus[$menuKey];
        if (!($menu instanceof menu_class)) {
            return -1;
        }
        else {
            return count($menu->children);
        }
    }
    public function AddItem($menuKey,$itemKey=null,menu_class $item) {
        if (isset($this->menus[$menuKey])) {
            $menu = $this->menus[$menuKey];
            if (!isset($itemKey) or (is_numeric($itemKey) &amp;amp;amp;&amp;amp;amp; $itemKey <0)) {
                $itemKey = count($menu->children);
            }
            $menu->AddSubItem($item,$itemKey,$menuKey);
        }
        return $this;
    }
    public function SetActive($id,$from=null) {
        $menu = new menu_class();
        if ($from == null) {
            $from = $this->menus;
        }
        elseif($from instanceof menu_class) {
            $from = $from->children;
        }
        foreach ($from as $key=>&amp;amp;amp;$menu) {
            if ($key==$id) {
                $menu->active=true;
                return true;
            }
            elseif(count($menu->children) !=0) {
                $r = $this->SetActive($id,$menu->children);
                if ($r) {
                    $menu->expanded = true;
                    return $r;
                }
            }
        }
    }
}
class menu_class {
    public $children = array();
    public $myParent=null;
    public $active = false;
    public $expanded = false;
    public $link ='';
    public $text = '';
    public $additional = array();

    public function AddSubItem($item,$ID=null,$parentID=null) {
        if ($item instanceof menu_class) {
        }
        elseif(is_array($item)) {
            $item = new menu_class();
            $item->text = $details[0];
            $item->link = $details[1];
        }
        if (isset($ID)) {
            if (isset($this->children[$ID])) {
                if (is_numeric($ID)) {
                    $this->children = array_insert($this->children,$item,$ID);
                }
            }
            else {
                $this->children[$ID] = $item;
            }
        }
        else {
            $this->children[] = $item;
        }
        if (!isset($parentID)) {
            $parentID = "main";
        }
        $this->myParent = $parentID;
        ksort($this->children);
    }

    public function __construct($text=null,$link=null) {
        if(isset($text) &amp;amp;amp;&amp;amp;amp; !is_null($text)) {
            $this->text = $text;
        }
        if(isset($link) &amp;amp;amp;&amp;amp;amp; !is_null($link)) {
            $this->link = $link;
        }
    } 

    public function Format($text) {
        if (!empty($this->link)) {
            $text= str_replace("%href%",$this->link);
        }
        if (!empty($this->text)) {
            $text = str_replace("%text%",$this->text);
        }
        return $text;
    }
}

You will notice that i’ve used the array_insert function from my previous posting. This was why it was created, so that i could insert without worry that i would overwrite the code

here’s an example of using the code

$menus = new menuHandler();
$menus->AddMenu("main",new menu_class());
 $menus->AddItem("main",-1,new menu_class("TEXT","link.php"));
 $menus->AddItem("main",-1,new menu_class("TEXT2","link2.php"));
//we want this item to be 1st!
 $menus->AddItem("main",0,new menu_class("1st Link","homelink.php"));

So far I pass the $menus out to smarty in the usual assignment method and process like as follows

 {foreach from=$menus.main->children item="mItem"}
  <div class="mainbutton"><a href="{$mItem->link}">{$mItem->text}</a></div>
 {/foreach}

For a cascaded menu i’ve used the following

{foreach from=$menus.cats->children item='cat'}
  <div class="item{if $cat->active || $cat->expanded}_select{/if}">
    <div class="arrow"></div>
    {if !$cat->active}<a href="{$cat->link}">{/if}{$cat->text}{if !$cat->active}</a>
    {/if}
  </div>
  {if $cat->children|@count ne 0 || $cat->expanded}
    {foreach from=$cat->children item='subCat'}
      <div class="subitem{if $subCat->active}_select{/if}">
        <div class="arrow"></div>
      {if !$subCat->active}<a href="{$subCat->link}">{/if}{$subCat->text}{if !$subCat->active}</a>{/if}
      </div>
    {/foreach}
  {/if}
  {/foreach}

As usual any comments gratefully recieved

Posted in PHP.

Tagged with , , , , .


0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.



Some HTML is OK

or, reply to this post via trackback.


Get Adobe Flash playerPlugin by wpburn.com wordpress themes