cached) { * echo $p->toHTML(); * return; * } * // add absolute URLs * $p->setroot('/', 'Home', 'Back to Home'); * $p->add('/cv/', 'CV', 'Curriculum Vitae'); * // create child * $q = new NavSystem(); * $q->setroot('/submenu/', 'Grouping Folder', ''); * $q->add('/1/', 'Thing 1', ''); * $q->add('/2/about.php', 'Thing 2', ''); * $q->add('http://www.google.com/', 'BBC', 'asd'); *$p->add($q); * $p->add('/bottom/', 'Thing at Bottom', 'bottom'); * echo $p->toHTML(); * @version 0.1 * @Copyright Vodex (vodex.net) 2005 * ABSOLUTELY NO WARRANTY: license at http://www.opensource.org/licenses/lgpl-license.php * Version 0.1: Initial release */ class NavSystem { /** * Holds menu data */ var $data = array(); /** * Holds current URL */var $current_url = null; /** * States if menu data was loaded from cache */ var $cached = false; /* * Holds cache data */ var $cache_file = null; /** * Adds a menu item or menu folder to the menu. Optionally accepts a local file name which will cache both menu structure and per-URL HTML * * @param string $cache_file */ function NavSystem($cache_file = null) { if ($cache_file) { $this->cache_file = $cache_file; // see if we have the menu structure living in cache $cache = @file($this->cache_file); if ($cache) { $this->data = unserialize($cache[0]); $this->cached = true; } } // get current location $this->setCurrentURL(); } /** * Adds a menu item or menu folder to the menu * * @param NavSystem or string $link * @param string $text * @param string $desc */ function add($link, $text = null, $desc = null) { // check if $link is a string or NavSystem object; is_a for non-PHP5 hosts if (is_a ($link , 'NavSystem')) { $this->data[] = $link; return; } $link = (string) $link; $text = (string) $text; $desc = (string) $desc; // only add if enough data provided if ($link > '' &$text > '') { $this->data[] = array('link' => $link, 'text' => $text, 'desc' => $desc); } } /** * Defines the root item (usually 'home' or root of folder) * * @param string $link * @param string $text * @param string $desc */ function setroot($link, $text, $desc = null) { $link = (string) $link; $text = (string) $text; $desc = (string) $desc; // if there's a root already defined, replace if ($this->data[0]['root']) { $this->data[0] = array('root' => 'true', 'link' => $link, 'text' => $text, 'desc' => $desc); } else { // create root array_unshift($this->data, array('root' => 'true', 'link' => $link, 'text' => $text, 'desc' => $desc)); } } /** * Sets the URL of the invoking page */ function setCurrentURL() { $url = $_SERVER['REQUEST_URI']; // strip off querystring $q = strpos($url, '?'); if ($q != false) { $url = substr($url, 0, $q); } $this->current_url = $url; if ($this->cache_file) { // we are caching, also locate cache of menu HTML $this->url_cache_file = $this->cache_file . md5($url); } } /** * Determines if the current URL in in the menu structure */ function hasCurrentURL() { // find if a URL exists within the structure if (count($this->data) > 0) { $url = $this->current_url; foreach ($this->data as $k => $v) { // var_dump($v); if (is_a ($v , 'NavSystem')) { // recurse to child $return = $v->hasCurrentURL(); if ($return) { // found return true; } } else { if ($v['link'] == $url) { // found return true; } } } } return false; } /** * Caches the menu structure, which is the only state we want to persist */ function cache_data() { // cache the structure, if not already loaded from cache if (!$this->cached) { // for PHP5+, we'd use file_put_contents $handle = fopen($this->cache_file, 'w'); if ($handle) { fwrite($handle, serialize($this->data)); fclose($handle); } } } /** * Caches HTML for a given URL */ function cache_html($html) { // cache the structure if not already cached // for PHP5+, we'd use file_put_contents $handle = fopen($this->url_cache_file, 'w'); if ($handle) { fwrite($handle, $html); fclose($handle); } } /** * Renders HTML of the menu. Does some initiailisation first, and then delegates to ::_ToHTML */ function ToHTML() { if ($this->cache_file) { // we are caching; cache the data $this->cache_data(); // and let's see if the menu HTML is cached $html = @file($this->url_cache_file); if ($html) { // file reads in a line at a time into array return join($html, ""); } } // begin rendering the menu; we always expand the first level $html=null; $html.= "
\n"; if ($this->url_cache_file) { // cache HTML $this->cache_html($html); } return $html; } /** * Iterates through the structure, expanding if current URL is within folder. If $top_level is true, then expand anyway and don't next the next level, so that 'home' and first menu choices are on the same level */ function _ToHTML($top_level = false) { if (count($this->data) > 0) { $html = null; $expand = ($top_level || $this->hasCurrentURL()); // show root entry $html .= $this->do_li($this->data[0]); if ($expand) { // expand the menu, either by force or because current url is inside if (!$top_level) { $html .= "