Documentation is available at treemenu-defs.php
- <?php
- /* ******************************************************************** */
- /* CATALYST PHP Source Code */
- /* -------------------------------------------------------------------- */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation; either version 2 of the License, or */
- /* (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with this program; if not, write to: */
- /* The Free Software Foundation, Inc., 59 Temple Place, Suite 330, */
- /* Boston, MA 02111-1307 USA */
- /* -------------------------------------------------------------------- */
- /* */
- /* Filename: treemenu-defs.php */
- /* Author: Paul Waite */
- /* Description: Definitions for a non-javascript multi-level (tree) */
- /* menu system, in vertical rendering. */
- /* */
- /* ******************************************************************** */
- /** @package menu */
- include_once("menu-defs.php");
- // ----------------------------------------------------------------------
- /**
- * A hierarchical menu renderer which does not use Javascript to
- * implement the menuoption display.
- * @package menu
- */
- class treemenu extends RenderableObject {
- // Public
- /** Menu name eg: 'main' */
- var $menu_name = "";
- /** Menu language, or default if zero */
- var $language = 0;
- /** Path to the stylesheet for menu */
- var $stylesheet = "";
- /** Overall class for the menu table */
- var $Tablestyle = "none";
- /** Alignment of the menu table */
- var $Align = "left";
- /** Colour of normal top menu item text */
- var $LowColor = "black";
- /** Colour of normal top menu item background */
- var $LowBgColor = "white";
- /** Colour of highlighted top menu item text */
- var $HighColor = "white";
- /** Colour of highlighted top menu item background */
- var $HighBgColor = "black";
- /** Colour of top menu item border */
- var $BorderColor = "black";
- /** Width of top menu border in px */
- var $BorderWidth = "";
- /** Colour of sub-menu item normal text */
- var $SubLowColor = "#efefef";
- /** Colour of sub-menu item background */
- var $SubLowBgColor = "#666666";
- /** Colour of sub-menu highlighted item text */
- var $SubHighColor = "white";
- /** Colour of sub-menu highlighted item background */
- var $SubHighBgColor = "#666666";
- /** Colour of sub-menu border */
- var $SubBorderColor = "black";
- /** Width of sub-menu border in px */
- var $SubBorderWidth = "";
- /** Fixed menu width, or zero if not fixed */
- var $menu_width = 0;
- /** Size of level indent padding in px */
- var $padsize = 10;
- /** Padding between menuoption image, and menu item text
- in pixels */
- var $label_padding_left = 0;
- /** Padding before (above) the top-level menu options */
- var $top_item_spacing = 0;
- /** Padding before (above) menu options which are
- headings for sub-menus */
- var $heading_item_spacing = 0;
- /** Padding before (above) 'pseudo' menu options */
- var $pseudo_item_spacing = 0;
- /** Padding before (above) 'normal' menu options */
- var $item_spacing = 0;
- // Private
- /** The menu instance
- @access private */
- var $menu;
- /** Unique database menu ID
- @access private */
- var $menu_id = 0;
- /** The current user session ID
- @access private */
- var $session_id;
- /** Whether this menu exists in the database
- @access private */
- var $exists = false;
- /** Initial menuoption ID
- @access private */
- var $menuoption_id;
- /** Image to use for collapsed sub-menu
- @access private */
- var $expandimage;
- /** Image to use for expanded sub-menu
- @access private */
- var $collapseimage;
- /** Image to use to indicate a menu option
- @access private */
- var $menuopimage;
- /** Image to use for padding/indenting menu options
- @access private */
- var $padimage;
- // ....................................................................
- /**
- * Constructor
- * Create a new menumaintainer.
- * @param string $menu_name Menu name
- * @param object $webpage Webpage object that this menu is being created for
- * @param string $stylsheet Name of stylesheet file to reference for menu styles
- * @param integer $lang Optional language variant of this menu (0 = default)
- */
- function treemenu($menu_name="main", $webpage=false, $stylesheet="", $lang=-1) {
- global $RESPONSE, $LIBDIR, $cachecontrol;
- // Default these standard images..
- $this->expandimage = new img("$LIBDIR/img/_plus.gif", "Expand", "Expand", 9, 9);
- $this->collapseimage = new img("$LIBDIR/img/_minus.gif", "Collapse", "Collapse", 9, 9);
- $this->menuopimage = new img("$LIBDIR/img/_mop.gif", "", "", 9, 9);
- $this->padimage = new img("$LIBDIR/img/_pad.gif", "", "", 1, 1);
- // Set menu name..
- $this->menu_name = $menu_name;
- // Set the menu language..
- if ($lang != -1) {
- $this->language = $lang;
- }
- elseif ($webpage !== false && $webpage->multilang && isset($webpage->languages[0])) {
- $this->language = $webpage->languages[0];
- }
- elseif (isset($RESPONSE) && $RESPONSE->multilang && isset($RESPONSE->languages[0])) {
- $this->language = $RESPONSE->languages[0];
- }
- // Check if we can use a menu stored in the session..
- // Manage selected menuoption..
- if (is_object($webpage) && $webpage->cachecontrol != "refresh") {
- $this->session_id = $webpage->session_id;
- if ($webpage->session_record["menu_status"] != "") {
- debugbr("unserializing menu..");
- $menu = unserialize($webpage->session_record["menu_status"]);
- if (is_object($menu) && $menu->valid
- && ($menu->menu_name == $this->menu_name && $menu->language == $this->language)) {
- debugbr("installing pre-existing menu..");
- $this->menu = $menu;
- if ($this->menu->get_if_modified()) {
- debugbr("rebuilt modified menu..");
- $this->save_to_session();
- }
- }
- }
- }
- // Create it if it doesn't exist, re-create if required..
- if (!isset($this->menu)) {
- $this->menu = new menu_instance($this->menu_name, $this->language);
- debugbr("treemenu: new menu generated", DBG_DEBUG);
- }
- // Find the stylesheet, check for changes..
- $this->webpage = ($webpage === false) ? $RESPONSE : $webpage;
- if ($this->webpage->head->stylesheet != "") {
- $this->get_styles();
- }
- // If valid, continue processing..
- if ($this->menu->valid) {
- $this->menu_id = $this->menu->menu_id;
- $this->exists = true;
- // This processes the menu option selected and makes any
- // necessary adjustments to menu structure, and saves it..
- $this->process_navigation();
- }
- } // treemenu
- // ....................................................................
- /**
- * Process any menu navigation.
- * This means we take note of any $_mid value which signifies a menu
- * option of that ID is currently being focussed on and alter the menu
- * configuration accordingly. We also look at the current page and
- * compare that to the menu id 'action' to determine where we are and
- * what we should be doing.
- * @access private
- */
- function process_navigation() {
- global $_mid, $RESPONSE;
- if ($this->exists) {
- if (isset($_mid) && $this->menu->menuop_exists($_mid)) {
- $this->menu->current_menu_option = $_mid;
- $selmop = $this->menu->menuop($_mid);
- if ($selmop !== false && $selmop->is_submenuheading()) {
- $selmop->expanded = !$selmop->expanded;
- $this->menu->menu_ops[$_mid] = $selmop;
- }
- // Save the updated menu instance object..
- $this->save_to_session();
- }
- }
- } // process_navigation
- // ....................................................................
- /**
- * This method saves the menu_instance to the user session for next
- * time. This gives the menu persistence.
- * @access private
- */
- function save_to_session() {
- $up = new dbupdate("ax_wwwsession");
- $up->set("menu_status", serialize($this->menu));
- $up->where("session_id='$this->session_id'");
- $up->execute();
- } // save_to_session
- // ....................................................................
- /**
- * Obtain the non-standard styles from the stylesheet
- */
- function get_styles() {
- // Get fonts and colours etc. If this stylesheet is undefined or
- // doesn't exist on disk, then we should still be able to generate
- // the vars below, but will get the defaults in each case..
- if (isset($this->webpage->head)) {
- $ss = new stylesheet($this->webpage->site_docroot . $this->webpage->head->stylesheet);
- // Read in all the style settings..
- $this->Tablestyle = defaulted($ss->style("menu", "menu-tablestyle"), "none");
- $this->Align = defaulted($ss->style("menu", "menu-align"), "left");
- $this->VerticalAlign = defaulted($ss->style("menu", "menu-vertical-align"), "left");
- $this->LowColor = defaulted($ss->style("menu", "color"), "black");
- $this->LowBgColor = defaulted($ss->style("menu", "background-color"), "white");
- $this->HighColor = defaulted($ss->style("menu_highlight", "color"), "white");
- $this->HighBgColor = defaulted($ss->style("menu_highlight", "background-color"), "black");
- $this->BorderColor = defaulted($ss->style("menu", "border-color"), "black");
- $this->BorderWidth = defaulted($ss->style("menu", "border-width"), "");
- $this->SubLowColor = defaulted($ss->style("submenu", "color"), "#efefef");
- $this->SubLowBgColor = defaulted($ss->style("submenu", "background-color"), "#666666");
- $this->SubHighColor = defaulted($ss->style("submenu_highlight", "color"), "white");
- $this->SubHighBgColor = defaulted($ss->style("submenu_highlight", "background-color"), "#666666");
- $this->SubBorderColor = defaulted($ss->style("submenu", "border-color"), "black");
- $this->SubBorderWidth = defaulted($ss->style("submenu", "border-width"), "");
- // Menu fixed width. Zero means not fixed..
- $val = defaulted($ss->style("menu", "menu-fixed-width"), "0px");
- $this->menu_width = str_replace("px", "", $val);
- // Padding which is inserted just before the text menu option labels..
- $val = defaulted($ss->style("menu", "label-padding-left"), "0px");
- $this->label_padding_left = str_replace("px", "", $val);
- // Vertical spacing above level0 top menu options..
- $val = defaulted($ss->style("menu", "top-item-spacing"), "0px");
- $this->top_item_spacing = str_replace("px", "", $val);
- // Vertical spacing above heading submenu-options. These
- // are the parent options of non-top-level sub-menus..
- $val = defaulted($ss->style("menu", "heading-item-spacing"), "0px");
- $this->heading_item_spacing = str_replace("px", "", $val);
- // Vertical spacing above 'pseudo' menu options..
- $val = defaulted($ss->style("menu", "pseudo-item-spacing"), "0px");
- $this->pseudo_item_spacing = str_replace("px", "", $val);
- // Vertical spacing above 'normal' menu options..
- $val = defaulted($ss->style("menu", "item-spacing"), "0px");
- $this->item_spacing = str_replace("px", "", $val);
- // Padding size of level indentation is determined by the overlap factor..
- $overlap = defaulted($ss->style("menu", "child-overlap"), "0.96");
- if ($overlap > 1) $overlap = 1;
- $width = ($this->menu_width > 0) ? $this->menu_width : 200;
- $this->padsize = floor((1 - $overlap) * $width);
- $val = defaulted($ss->style("menu", "show-arrows"), "no");
- $this->ShowArrow = ($val == "yes");
- }
- } // get_styles
- // ....................................................................
- /**
- * Over-rides the standard '+' and '-' icon images used to indicate a
- * sub-menu can be expanded or collapsed. The values passed should be
- * image image objects as instances of the 'img' class (@see img()).
- * @param object $expandimg New image for 'expand' graphic
- * @param object $collapseimg New image for 'collapse' graphic
- * @param object $mopimg New image for 'menu option' graphic
- * @param object $padimg New image for 'pad' graphic
- */
- function set_menu_images($expandimg=false, $collapseimg=false, $menuopimg=false, $padimg=false) {
- if ($expandimg !== false) {
- $this->expandimage = $expandimg;
- }
- if ($collapseimg !== false) {
- $this->collapseimage = $collapseimg;
- }
- if ($menuopimg !== false) {
- $this->menuopimage = $menuopimg;
- }
- if ($padimg !== false) {
- $this->padimage = $padimg;
- }
- } // set_menu_images
- // ....................................................................
- /**
- * Process a menu entry/option/item and return the HTML rendering
- * of it as it would sit in the menu. We also process child options
- * of the given option by iteration.
- * @param object $Tmenu The table object the menu is being built in
- * @param string $prefix The prefix string for the menu option
- * @param integer $mopid The menu option ID of this menu option
- * @return object The modified menu table object
- * @access private
- */
- function menu_entry($Tmenu, $prefix, $mopid) {
- global $LIBDIR, $RESPONSE;
- static $first = true;
- $childcount = 0;
- $s = "";
- // Store current menu option..
- $mop = $this->menu->menuop($mopid);
- if ($mop !== false) {
- $details = $mop->details();
- $menu_level = $mop->menu_level;
- $label = $mop->label;
- $action = $mop->action;
- $target = $mop->target;
- $expanded = $mop->expanded;
- $heading = $mop->is_submenuheading(); // Whether it is a heading for sub-menu
- $pseudo = $mop->is_pseudo(); // Whether it is a pseudo menu-item
- $menuoption = !$heading;
- // Set up menu/submenu styling..
- if ($menu_level == 0) {
- $class = "menu";
- $hicolour = $this->HighColor;
- $hibg = $this->HighBgColor;
- $border = $this->BorderWidth;
- }
- else {
- $class = "submenu";
- $hicolour = $this->SubHighColor;
- $hibg = $this->SubHighBgColor;
- $border = $this->SubBorderWidth;
- }
- // Non-pseudo menu-items first..
- if (!$pseudo) {
- if ($heading) {
- // Widgets for headings (non-menuoptions)..
- if ($expanded) {
- $widget = $this->collapseimage;
- }
- else {
- $widget = $this->expandimage;
- }
- // Link to current page for refresh..
- if ($action == "") {
- $action = $RESPONSE->requested;
- if ($RESPONSE->requested_query != "") {
- $action .= "?$RESPONSE->requested_query";
- }
- }
- }
- else {
- // padding for standard menuoption..
- if ($menu_level > 0) {
- if ($this->ShowArrow) {
- $widget = $this->menuopimage;
- }
- else {
- $widget = $this->padimage;
- $widget->setwidth($this->padsize);
- }
- }
- else {
- $widget = $this->padimage;
- $widget->setwidth($this->padsize);
- }
- }
- //$widget->sethspace(2);
- // Add selected menu option id to URL, but only if it is
- // not an off-site URL of some kind..
- if (!protocol_prefixed($action)) {
- $action = href_addparm($action, "_mid", $mopid);
- // Make sure our menu gets refreshed and not stuck in a static
- // state in the web-browser's cache..
- $action = href_addparm($action, "cachecontrol", "dynamic");
- }
- // Padding for this menu level..
- $padding = $this->padimage;
- $padding->setwidth($this->padsize * $menu_level);
- // Highlight if the current script name occurs in the item action..
- $style = "";
- $requestedurl = basename($RESPONSE->requested) . ($RESPONSE->requested_query != "" ? "\?$RESPONSE->requested_query" : "");
- $pad = new img("$LIBDIR/img/_pad.gif", "", "", $this->label_padding_left, 1);
- if (!$heading && preg_match("/$requestedurl/i", $action)) {
- $menuop = $padding->render() . $widget->render() . $pad->render() . $label;
- $style = "color:$hicolour;background-color:$hibg;";
- }
- // Create a clickable anchor link..
- else {
- $widget_link = new anchor($action, $widget->render());
- $menuop_link = new anchor($action, $label);
- if ($target != "") {
- $widget_link->settarget($target);
- $menuop_link->settarget($target);
- }
- $menuop = "";
- if ( $padding->width > 0 ) {
- $menuop .= $padding->render();
- }
- $menuop .= $widget_link->render() . $pad->render() . $menuop_link->render();
- }
- }
- // Deal with pseudo menu-items here..
- else {
- switch ($label) {
- case MENU_ITEM_SEPARATOR:
- // This results in a separator line 1px wide..
- $menuop = "<table border=0 cellspacing=0 cellpadding=0 width=\"100%\" ";
- $menuop .= "style=\"background-color:$this->LowColor\">";
- $menuop .= "<tr><td></td></tr>";
- $menuop .= "</table>";
- break;
- default:
- // 1-pixel placeholder, so we have some content..
- $pad = new img("$LIBDIR/img/_pad.gif", "", "", 1, 1);
- $menuop = $pad->render();
- } // switch
- }
- // Borders, if any..
- if ($border != "" && substr($border,0,1) != "0") {
- if ($first) {
- $style .= "border-width:$border;";
- }
- else {
- $style .= "border-width:0px $border $border $border;";
- }
- }
- if ($first) $first = false;
- // Render menu item/option..
- $Tmenu->tr();
- $Tmenu->td($menuop, $class);
- if ($style != "") {
- $Tmenu->td_css($style);
- }
- // Spacing and padding styles..
- $top_spacing = 0;
- $bot_spacing = 0;
- if ($pseudo) {
- $spacing = ($this->pseudo_item_spacing > 0) ? $this->pseudo_item_spacing : $this->item_spacing;
- $top_spacing = ceil($spacing / 2);
- $bot_spacing = $spacing - $top_spacing;
- $Tmenu->td_alignment("","middle");
- }
- elseif ($menu_level == 0) {
- $top_spacing = $this->top_item_spacing;
- }
- elseif ($heading) {
- $top_spacing = $this->heading_item_spacing;
- }
- else {
- $top_spacing = $this->item_spacing;
- }
- // Apply any spacing which eventuated..
- if ($top_spacing > 0) {
- $Tmenu->td_css("padding-top:" . $top_spacing . "px");
- }
- if ($bot_spacing > 0) {
- $Tmenu->td_css("padding-bottom:" . $bot_spacing . "px");
- }
- // And now do the children of sub-menu heading..
- //if ($heading && $expanded) {
- if ($expanded) {
- if (isset($mop->children) && $mop->children != "") {
- $childoptions = explode("|", $mop->children);
- $childcount = count($childoptions);
- $pfxcount = 1;
- foreach ($childoptions as $childmopid) {
- $childprefix = $prefix . "|" . $pfxcount;
- $Tmenu = $this->menu_entry($Tmenu, $childprefix, $childmopid);
- $pfxcount += 1;
- }
- }
- }
- }
- // Return the menu table..
- return $Tmenu;
- } // menu_entry
- // ....................................................................
- /**
- * Render the menu as HTML. Please note that the TreeMenu is by design
- * a VERTICAL menu system, so don't expect the 'orientation' style in
- * the stylesheet to have any effect for this class.
- * @return string The HTML
- */
- function html() {
- debug_trace($this);
- global $LIBDIR, $RESPONSE;
- global $_mid;
- // Menu layout table..
- $Tmenu = new table($this->menu_id . "_menu", "");
- $Tmenu->setalign($this->Align);
- $Tmenu->setvalign($this->VerticalAlign);
- if ($this->menu_width > 0) {
- $Tmenu->setwidth($this->menu_width);
- }
- else {
- $Tmenu->setwidth("100%");
- }
- // Apply given tablestyle class..
- if ($this->Tablestyle != "none") {
- $Tmenu->setclass($this->Tablestyle);
- }
- // MENU ITEM DETAIL..
- if ($this->menu->menuop_count() > 0) {
- // Store each row..
- foreach ($this->menu->menu_top as $item_no => $mopid) {
- $prefix = "$item_no";
- $Tmenu = $this->menu_entry($Tmenu, $prefix, $mopid);
- }
- }
- // Render the menu viewer table..
- return $Tmenu->render();
- } // html
- } // treemenu class
- // ----------------------------------------------------------------------
- ?>
Documentation generated by phpDocumentor 1.3.0RC3