1<?php 2 /* libraries/menu.php 3 * 4 * Copyright (C) by Hugo Leisink <hugo@leisink.net> 5 * This file is part of the Banshee PHP framework 6 * http://www.banshee-php.org/ 7 */ 8 9 class menu { 10 private $db = null; 11 private $output = null; 12 private $parent_id = 0; 13 private $depth = 1; 14 private $user = null; 15 16 /* Constructor 17 * 18 * INPUT: object database, object output 19 * OUTPUT: - 20 * ERROR: - 21 */ 22 public function __construct($db, $output) { 23 $this->db = $db; 24 $this->output = $output; 25 } 26 27 /* Set menu start point 28 * 29 * INPUT: string link 30 * OUTPUT: true 31 * ERROR: false 32 */ 33 public function set_start_point($link) { 34 $query = "select id from menu where link=%s limit 1"; 35 if (($menu = $this->db->execute($query, $link)) == false) { 36 return false; 37 } 38 39 $this->parent_id = (int)$menu[0]["id"]; 40 41 return true; 42 } 43 44 /* Set menu depth 45 * 46 * INPUT: int depth 47 * OUTPUT: - 48 * ERROR: - 49 */ 50 public function set_depth($depth) { 51 if (($this->depth = (int)$depth) < 1) { 52 $this->depth = 1; 53 } 54 } 55 56 /* Set user for access check 57 * 58 * INPUT: object user 59 * OUTPUT: - 60 * ERROR: - 61 */ 62 public function set_user($user) { 63 $this->user = $user; 64 } 65 66 /* Get menu data 67 * 68 * INPUT: int menu identifier[, int menu depth][, string link of active menu item for highlighting] 69 * OUTPUT: array menu data 70 * ERROR: false 71 */ 72 private function get_menu($id, $depth = 1, $current_url = null) { 73 $query = "select * from menu where parent_id=%d order by %S"; 74 if (($menu = $this->db->execute($query, $id, "id")) === false) { 75 return false; 76 } 77 78 $result = array( 79 "id" => $id, 80 "items" => array()); 81 82 foreach ($menu as $item) { 83 $element = array(); 84 85 if (($this->user !== null) && ($item["link"][0] == "/")) { 86 if (($module = ltrim($item["link"], "/")) != "") { 87 if ($this->user->access_allowed($module) == false) { 88 continue; 89 } 90 } 91 } 92 93 $element["id"] = $item["id"]; 94 if ($current_url !== null) { 95 $element["current"] = show_boolean($item["link"] == $current_url); 96 } 97 $element["text"] = $item["text"]; 98 $element["link"] = $item["link"]; 99 if ($depth > 1) { 100 $element["submenu"] = $this->get_menu($item["id"], $depth - 1, $current_url); 101 } 102 103 array_push($result["items"], $element); 104 } 105 106 return $result; 107 } 108 109 /* Print menu to output 110 * 111 * INPUT: array menu data 112 * OUTPUT: - 113 * ERROR: - 114 */ 115 private function show_menu($menu) { 116 if (count($menu) == 0) { 117 return; 118 } 119 120 $this->output->open_tag("menu", array("id" => $menu["id"])); 121 foreach ($menu["items"] as $item) { 122 $args = array("id" => $item["id"]); 123 if (isset($item["current"])) { 124 $args["current"] = $item["current"]; 125 } 126 127 $this->output->open_tag("item", $args); 128 $this->output->add_tag("link", $item["link"]); 129 $this->output->add_tag("text", $item["text"]); 130 if (isset($item["submenu"])) { 131 $this->show_menu($item["submenu"]); 132 } 133 $this->output->close_tag(); 134 } 135 $this->output->close_tag(); 136 } 137 138 /* Appent menu to XML output 139 * 140 * INPUT: [string link of active menu item for highlighting] 141 * OUTPUT: true 142 * ERROR: false 143 */ 144 public function to_output($current_url = null) { 145 /* Handle menu updates 146 */ 147 $cache = new cache($this->db, "menu"); 148 if ($cache->last_updated === null) { 149 $cache->store("last_updated", time(), 365 * DAY); 150 } 151 if (isset($_SESSION["menu_last_updated"]) == false) { 152 $_SESSION["menu_last_updated"] = $cache->last_updated; 153 } else if ($cache->last_updated > $_SESSION["menu_last_updated"]) { 154 $_SESSION["menu_cache"] = array(); 155 $_SESSION["menu_last_updated"] = $cache->last_updated; 156 } 157 unset($cache); 158 159 /* Build menu 160 */ 161 if (isset($_SESSION["menu_cache"]) == false) { 162 $_SESSION["menu_cache"] = array(); 163 } 164 $cache = &$_SESSION["menu_cache"]; 165 166 $username = ($this->user !== null) ? $this->user->username : ""; 167 $index = sha1(sprintf("%d-%d-%s-%s", $this->parent_id, $this->depth, $username, $current_url)); 168 169 if (isset($cache[$index]) == false) { 170 if (($menu = $this->get_menu($this->parent_id, $this->depth, $current_url)) === false) { 171 return false; 172 } 173 $cache[$index] = json_encode($menu); 174 } else { 175 $menu = json_decode($cache[$index], true); 176 } 177 178 $this->show_menu($menu); 179 180 return true; 181 } 182 } 183?> 184