Documentation is available at menu-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: menu-defs.php */
- /* Author: Paul Waite */
- /* Description: Definitions for managing MENUS */
- /* */
- /* ******************************************************************** */
- /** @package menu */
- include_once("button-defs.php");
- /** Form elements */
- ("form-defs.php");
- /** User management */
- ("user-defs.php");
- // ----------------------------------------------------------------------
- // DEFINITIONS
- /** Menu orientation set to horizontal */
- ("HORIZONTAL", 1);
- /** Menu orientation set to vertical */
- ("VERTICAL", 2);
- // Separators for horizontal menus. Note, usage of at least
- // one real space, so that we allow wrapping in cells..
- /** Menu item separator: " " (space) */
- ("SEP_SPACE", " ");
- /** Menu item separator: "|" (pipe) */
- ("SEP_BAR", " | ");
- /** Menu item separator: " " (double-space) */
- ("SEP_DBLSPACE", " ");
- // Some menu levels..
- /** Main menu level (0) */
- ("MENU_LEVEL0", 0);
- /** Menu level 1 */
- ("MENU_LEVEL1", 1);
- /** Menu level 2 */
- ("MENU_LEVEL2", 2);
- /** Menu level 3 */
- ("MENU_LEVEL3", 3);
- /** Menu level 4 */
- ("MENU_LEVEL4", 4);
- /** All menu levels */
- ("MENU_LEVEL_ALL", -1);
- // Patterns for special-function menu items. These are really
- // psuedo menu items, rather than real ones which navigate
- // the user to a web-page target.
- /** The menu item is a sub-menu heading */
- ("MENU_ITEM_SUBMENU", "(sub-menu only)");
- /** The menu item is a spacer */
- ("MENU_ITEM_SPACER", "(menu spacer)");
- /** The menu item is a separator line */
- ("MENU_ITEM_SEPARATOR", "(menu separator)");
- /** The menu item is an ad-hoc URL */
- ("MENU_ITEM_URL", "(ad-hoc URL)");
- // ----------------------------------------------------------------------
- /**
- * Label class
- * A class for managing a simple label. This is just a piece of text
- * with some font settings.
- * @package menu
- * @access private
- */
- class label extends RenderableObject {
- /** Text of the label */
- var $text = "";
- /** Font setting for the label */
- var $font = "";
- //.....................................................................
- /**
- * Constructor
- * Creates the basic label object.
- * @param string $text Text of the label
- * @param string $font Font settings to apply to the label
- */
- function label($text="", $font="") {
- $this->text = $text;
- $this->font = $font;
- }
- //.....................................................................
- /**
- * Set the label font
- * @param string $font Font settings to apply to the label
- */
- function set_font($font) {
- $this->font = $font;
- return $this;
- }
- // ....................................................................
- /**
- * Use render() to render this element in your page.
- * This renders the field as WML.
- * @see render()
- * @return string The field as WML.
- */
- function wml() {
- return $this->text;
- }
- // ....................................................................
- /**
- * Use render() to render this element in your page.
- * This renders the field as HTML.
- * @see render()
- * @return string The field as HTML.
- */
- function html() {
- $html = "";
- if (isset($this->font)) $html .= "<font " . $this->font . ">";
- $html .= $this->text;
- if (isset($this->font)) $html .= "</font>";
- return $html;
- }
- } // label
- // ----------------------------------------------------------------------
- /**
- * Standard menu item. Takes a link object as the item in the menu.
- * @package menu
- */
- class menuitem extends RenderableObject {
- // Public
- /** Link object to associate with menu item */
- var $link;
- /** Label for this menu item */
- var $label = "";
- // Private
- /** True if menu item is highlighted
- @access private */
- var $highlighted = false;
- /** ID of parent menuitem of this menuitem
- @access private */
- var $parent_id = 0;
- /** Menu level of this item
- @access private */
- var $menu_level = 0;
- //.....................................................................
- /**
- * Constructor
- * Creates the menu item object.
- * @param object $link Link object to associate with menu item
- * @param boolean $highlighted Whether item is highlighted or not
- * @param integer $parent_id ID of parent menuitem (or 0 if none)
- * @param integer $menu_level Level of this item (zero-based)
- */
- function menuitem($link, $highlighted=false, $parent_id=0, $menu_level=0) {
- $this->link = $link;
- $this->label = new label($link->label);
- $this->highlighted = $highlighted;
- $this->parent_id = $parent_id;
- $this->menu_level = $menu_level;
- } // menuitem
- //.....................................................................
- /**
- * Set the menu item font
- * @param string $font Font settings to apply to the menu item
- */
- function set_font($font) {
- $this->link = $this->link->set_font($font);
- $this->label = $this->label->set_font($font);
- return $this;
- } // set_font
- // ....................................................................
- /**
- * This renders the field as WML.
- * @return string The field as WML.
- */
- function wml() {
- return "<small>" . $this->link->wml() . "</small>";
- } // wml
- // ....................................................................
- /**
- * This renders the field as HTML.
- * @return string The field as HTML.
- */
- function html() {
- return $this->link->html();
- } // html
- } // menuitem class
- // ----------------------------------------------------------------------
- /**
- * A menu, which is a container for menu items. This class encapsulates
- * what is essentially a list of links which can be displayed as a
- * 'menu'. Orientation can be VERTICAL or HORIZONTAL. A 'wrap threshold'
- * can be defined. If it's a vertical menu, this represents the max no.
- * of items down the page. Extra columns are generated to the right to
- * accomodate the items list. In the horizontal case, the threshold
- * represents the max no. of items across the page. Extra rows are
- * generated to hold the menu items list.
- * @package menu
- */
- class menu extends StylableObject {
- // Public
- /** Name of the menu */
- var $name = "";
- /** Title/banner for this menu */
- var $title = "";
- /** Menu orientation: HORIZONTAL or VERTICAL */
- var $orientation = VERTICAL;
- /** Separator character between items */
- var $separator = SEP_SPACE;
- /** Stylesheet class to use for highlighting */
- var $highlightclass = "";
- // Private
- /** Array of items in this menu
- @access private */
- var $items;
- /** Number of items in the menu
- @access private */
- var $item_count = 0;
- /** Font settings for the title/banner
- @access private */
- var $title_font = "";
- /** Max. number of menu items before wrapping the menu
- @access private */
- var $wrap_threshold = 0;
- // ....................................................................
- /**
- * Constructor
- * Creates the menu object.
- * @param string $name Name of the menu
- * @param string $title Title/benner for the menu
- * @param string $orientation HORIZONTAL or VERTICAL
- * @param integer $wrap_threshold Max. number of menu items before menu wraps
- */
- function menu($name, $title="", $orientation=VERTICAL, $wrap_threshold=0) {
- $this->name = $name;
- $this->title = $title;
- $this->item_count = 0;
- $this->orientation = $orientation;
- $this->wrap_threshold = $wrap_threshold;
- // Default separator string..
- $this->separator = SEP_SPACE;
- // A default style for highlighted items. Define this
- // in your stylesheet to see items highlighted..
- $this->highlightclass = "menuitemHL";
- } // menu
- // ....................................................................
- /**
- * Add menu item
- * Adds a ready-made menuitem to the menu.
- * @param object $item The menu item to add to the menu
- */
- function add_menuitem($item) {
- $this->items[] = $item;
- $this->item_count += 1;
- return $this;
- } // add_menuitem
- // ....................................................................
- /**
- * Create new menu item
- * Makes a new menuitem from a given label and URL
- * and adds it to the menu.
- * @param string $label Label to display
- * @param string $url URl for the menu item link
- * @param string $linkover_text Text to display in status bar when mouseover
- * @param bool $highlighted True if menu item should be highlighted
- * @param integer $parent_id Parent ID of this new item
- * @param integer $menu_level menu level of this new item
- */
- function additem($label, $url, $linkover_text="", $highlighted=false, $parent_id=0, $menu_level=0) {
- $link = new Link($url, $label);
- if ($linkover_text != "") {
- $link->set_linkover_text($linkover_text);
- }
- $item = new menuitem($link, $highlighted, $parent_id, $menu_level);
- $this->add_menuitem($item);
- return $this;
- } // additem
- //.....................................................................
- /**
- * Set the font of all menu items
- * @param string $font Font settings to apply to all menu items
- */
- function set_itemfont($font) {
- for ($i=0; $i < $this->item_count; $i++) {
- $item = $this->items[$i];
- $this->items[$i] = $item->set_font($font);
- }
- return $this;
- } // set_itemfont
- //.....................................................................
- /**
- * Set the menu tite font
- * @param string $font Font settings for menu title
- */
- function set_titlefont($font) {
- $this->title_font = $font;
- return $this;
- } // set_titlefont
- // ....................................................................
- /**
- * This renders the menu as WML (w/Phone.com extns) in a paged mode
- * with a number of menuitems/page defined by $wrap_threshold.
- * WAP phone with Phone.com extensions. We always create vertical
- * menus using a jump-menu in this particular case.
- * @return string The menu as WML.
- */
- function wmlup() {
- global $RESPONSE;
- global $ipg;
- if (!isset($ipg)) $ipg = 1;
- $s = "";
- if ($this->title != "") {
- $s .= "<b>" . $this->title . "</b><br/>";
- }
- // Initialise..
- $paged = false;
- $start = 0;
- $finish = $this->item_count - 1;
- // Determine page if paged menu..
- if ($this->wrap_threshold > 0) {
- $paged = true;
- $start = ($ipg - 1) * $this->wrap_threshold;
- $finish = $start + $this->wrap_threshold - 1;
- if ($finish > ($this->item_count - 1)) {
- $finish = $this->item_count - 1;
- }
- }
- // Grab menu options we want, assemble jump-menu..
- $jump = new form_jumpmenu($this->name, $this->title);
- for ($ix=$start; $ix <= $finish; $ix++) {
- $item = $this->items[$ix];
- $link = $item->link;
- $jump->additem($link->label, $link->href);
- }
- // More.. link
- if ($paged) {
- $pglabel = ""; $nextlabel = ""; $nexthref = "";
- $this->wml_morelink($ipg, $pglabel, $nextlabel, $nexthref);
- if ($nexthref != "") {
- $jump->additem($nextlabel, $nexthref);
- }
- }
- // Render the menu options..
- $s .= $jump->render();
- if ($paged) {
- $s .= $pglabel;
- }
- // Return menu..
- return $s;
- } // wmlup
- // ....................................................................
- /**
- * This renders the field as WML.
- * @return string The field as WML.
- */
- function wml() {
- global $RESPONSE;
- global $ipg;
- if (!isset($ipg)) $ipg = 1;
- $s = "";
- if ($this->title != "") {
- $s .= "<b>" . $this->title . "</b><br/>";
- }
- // Initialise..
- $paged = false;
- $start = 0;
- $finish = $this->item_count - 1;
- // Determine page if paged menu..
- if ($this->wrap_threshold > 0) {
- $paged = true;
- $start = ($ipg - 1) * $this->wrap_threshold;
- $finish = $start + $this->wrap_threshold - 1;
- if ($finish > ($this->item_count - 1)) {
- $finish = $this->item_count - 1;
- }
- }
- // Grab menu options we want, assemble jump-menu..
- $jump = new form_jumpmenu($this->name, $this->title);
- for ($ix=$start; $ix <= $finish; $ix++) {
- $item = $this->items[$ix];
- $s .= $item->wml() . "<br/>";
- }
- if ($paged) {
- $pglabel = ""; $nextlabel = ""; $nexthref = "";
- $this->wml_morelink($ipg, $pglabel, $nextlabel, $nexthref);
- $s .= $pglabel;
- if ($nexthref != "") {
- $nextlink = new Link($nexthref, $nextlabel);
- $s .= $nextlink->render();
- }
- }
- // Return menu
- return $s;
- } // wml
- // ....................................................................
- /**
- * Given a page number of the current page, this method returns the
- * appropriate label and link HREF for the next page link.
- * @param integer $page Page number of current page
- * @param string $pagepos Reference to string to contain current page pos
- * @param string $nextlabel Reference to string to contain next page link
- * @param string $nexthref Reference to string to contain HREF to next page
- */
- function wml_morelink($page, &$pagepos, &$nextlabel, &$nexthref) {
- global $RESPONSE;
- $nextpage = $page;
- $totpages = ceil($this->item_count / $this->wrap_threshold);
- $pagepos = " [$page/$totpages] ";
- $nextlabel = ""; $nexthref = "";
- if ($this->item_count > $this->wrap_threshold) {
- if ($page * $this->wrap_threshold > $this->item_count) {
- $nextpage = 1;
- $nextlabel = "First..";
- }
- else {
- $nextpage = $page + 1;
- $nextlabel = "More..";
- }
- $nexthref = $RESPONSE->requested;
- if (substr($nexthref, 0, 1) == "/") $nexthref = substr($nexthref, 1);
- if ($RESPONSE->requested_query != "") {
- $nexthref .= "?" . str_replace("&", "&", $RESPONSE->requested_query);
- if (strstr($nexthref, "ipg=")) {
- $nexthref = preg_replace("/ipg=[0-9]+/", "ipg=$nextpage", $nexthref);
- }
- else {
- $nexthref .= "&ipg=$nextpage";
- }
- }
- else {
- $nexthref .= "?ipg=$nextpage";
- }
- }
- return $nextpage;
- } // wml_morelink
- // ....................................................................
- /**
- * This renders the field as HTML.
- * @return string The field as HTML.
- */
- function html() {
- if ($this->orientation == VERTICAL) {
- // The only feasible way of doing vertical menus is in a table..
- $Tm = new table($this->name);
- $Tm->inherit_attributes($this);
- // Metrics..
- if ($this->wrap_threshold > 0 && $this->item_count > $this->wrap_threshold) {
- $cols = (int) ($this->item_count / $this->wrap_threshold);
- $tail = $this->item_count % $this->wrap_threshold;
- if($tail > 0) $cols += 1;
- }
- else {
- $cols = 1;
- }
- // Title text at top-left..
- if ($this->title != "") {
- $Tm->tr();
- $title .= $this->title;
- if ( isset($this->title_font) ) $title = "<font " . $this->title_font . ">$title</font>";
- $Tm->td($title);
- $Tm->td_colspan($cols * 2);
- }
- // The items..
- $items_left = $this->item_count;
- $row = 0;
- while ($items_left > 0) {
- $Tm->tr();
- for ($c=0; $c < $cols; $c++) {
- $item_index = $row + ($c * $this->wrap_threshold);
- if ($item_index < $this->item_count) {
- $item = $this->items[$item_index];
- if ($item->highlighted) {
- $item->link->highlightclass = $this->highlightclass;
- }
- $Tm->td($item->html());
- $html .= "<td>";
- if (isset($item->button)) {
- $Tm->td($item->label->html());
- }
- else {
- $Tm->td();
- }
- $items_left -= 1;
- }
- } // for
- $row += 1;
- } // while
- }
- else { // HORIZONTAL
- // Title text at top-left..
- if ($this->title != "") {
- $html .= "<p>";
- if ( isset($this->title_font) ) $html .= "<font " . $this->title_font . ">";
- $html .= $this->title;
- if ( isset($this->title_font) ) $html .= "</font>";
- $html .= "</p>";
- }
- // The menu items..
- $items_left = $this->item_count;
- $row = 0;
- $html .= "<span";
- if ($this->class != "") {
- $html .= " class=\"" . $this->class . "\"";
- }
- if ($this->style != "") {
- $html .= " style=\"$this->style\"";
- }
- $html .= ">";
- while ($items_left > 0) {
- for ($c=0; ($this->wrap_threshold == 0 || $c < $this->wrap_threshold) && ($items_left > 0); $c++) {
- $item_index = $c + ($row * $this->wrap_threshold);
- $item = $this->items[$item_index];
- if ($items_left > 0) {
- if ($item->highlighted) {
- $item->link->highlightclass = $this->highlightclass;
- }
- $html .= $item->html();
- if ( isset($item->button) ) $html .= " " . $item->label->html();
- }
- $items_left -= 1;
- if ($items_left > 0) $html .= $this->separator;
- }
- $row += 1;
- $html .= "<br>";
- }
- $html .= "</span>";
- }
- return $html;
- } // html
- } // menu class
- // ----------------------------------------------------------------------
- /**
- * Site Menu class - a database-enabled extension of the menu class.
- * The menu is built from the standard library database menu structure. This
- * database structure comprises two tables: 'menu' and 'menuoption'. Use this
- * menu renderer for simple single-row or single-column menus. It is rendered
- * as a simple list of items as clickable links. It also automatically applies
- * highlighting to the option which has an 'action' which matches the current
- * $RESPONSE page.
- * @package menu
- */
- class sitemenu extends menu {
- /** Name of this menu eg: 'main' */
- var $menu_name = "";
- /** Level of menuitems to return */
- var $menu_level = MENU_LEVEL_ALL;
- /** Language variant of this menu eg: 'fr' */
- var $language = 0;
- // ....................................................................
- /**
- * Constructor
- * The name is used when rendering jump menu select boxes, the level is the menu
- * level starting at zero (default), the title is rendered above the list if specified,
- * orientation is VERTICAL or HORIZONTAL, wrap_threshold tells it where to wrap
- * to the next row (HORIZONTAL) or column (VERTICAL).
- * @param string $name Menu name used to identify the menu
- * @param integer $menu_level Level of menuitems to return
- * @param string $title Title/benner for this menu
- * @param integer $orientation HORIZONTAL or VERTICAL
- * @param integer $wrap_threshold Number of items before wrapping occurs
- * @param integer $lang Language variant for menu (or default if zero)
- */
- function sitemenu(
- $menuname="main",
- $menu_level=MENU_LEVEL_ALL,
- $title="",
- $orientation=VERTICAL,
- $wrap_threshold=0,
- $lang=-1
- ) {
- global $RESPONSE;
- $this->menu_name = $menuname;
- $this->menu_level = $menu_level;
- $this->menu($menuname, $title, $orientation, $wrap_threshold);
- // Set language..
- if ($lang != -1) {
- $this->language = $lang;
- }
- elseif (isset($RESPONSE) && $RESPONSE->multilang && isset($RESPONSE->languages[0])) {
- $this->language = $RESPONSE->languages[0];
- }
- // Get the menu definition..
- $this->getmenu();
- } // sitemenu
- // ....................................................................
- /**
- * Get the menu
- * Read the menuitems in from database and apply security..
- * @param string $id Unique database menu identifier
- */
- function getmenu($name="", $lang=-1) {
- global $RESPONSE;
- debug_trace($this);
- // Specific menu given..
- if ($name != "") $this->menu_name = $name;
- if ($lang != -1) $this->language = $lang;
- // Get menu, fall back to default if not found..
- $tryagain = true;
- do {
- $tryagain = ($this->language != 0);
- $q = "SELECT *";
- $q .= " FROM ax_menu m, ax_menuoption mo";
- $q .= " WHERE m.menu_name='" . escape_string($this->menu_name) . "'";
- $q .= " AND m.lang_id=$this->language";
- $q .= " AND mo.menu_id=m.menu_id";
- if ($this->menu_level != MENU_LEVEL_ALL) {
- $q .= " AND mo.menu_level=$this->menu_level";
- }
- $q .= " AND m.active=TRUE";
- $q .= " AND mo.active=TRUE";
- $q .= " ORDER BY mo.display_order";
- $item = dbrecordset($q);
- if ($item->hasdata) {
- $tryagain = false;
- }
- else {
- debugbr("menu language not found ($this->language): falling back to default", DBG_DEBUG);
- $this->language = 0;
- }
- } while ($tryagain);
- if ($item->hasdata) {
- $mnu_ugroups = $item->field("mnu_ugroups");
- if ($mnu_ugroups == "" || $RESPONSE->ismemberof_group_in($mnu_ugroups)) {
- do {
- // Only add it if item group membership satisfied..
- $item_ugroups = $item->field("user_groups");
- $item_usertype = $item->field("user_type");
- if ($item_ugroups == "" || $RESPONSE->ismemberof_group_in($item_ugroups)) {
- if ($item_usertype == "" || ($RESPONSE->user_type == $item_usertype)) {
- $auth_required = $item->istrue("auth_code");
- $action = $item->field("action");
- $label = $item->field("label");
- $desc = $item->field("description");
- $parent_id = $item->field("parent_id");
- $menu_level = $item->field("menu_level");
- // Build the menu URL..
- $href = $item->field("action");
- if ($auth_required) {
- if (strstr($href, "?")) $href .= "&";
- else $href .= "?";
- $href .= "auth_code=" . $RESPONSE->get_auth_code();
- }
- // Highlight if the current script name occurs in the item action..
- if (isset($action) && $action != "") {
- $highlighted = stristr(basename($RESPONSE->requested), $action);
- }
- // Add to our menu..
- $this->additem($label, $href, $desc, $highlighted, $parent_id, $menu_level);
- } // user type check
- } // item groups allowed
- } while ($item->get_next());
- } // menu groups allowed
- }
- debug_trace();
- } // getmenu
- } // sitemenu class
- // ----------------------------------------------------------------------
- /**
- * The menuoption is a class which contains the properties of a single
- * option on a menu.
- * @package menu
- */
- class menuoption extends RenderableObject {
- // Public
- /** Menuoption displayed label */
- var $label = "(new item)";
- /** Menu option descriptive text */
- var $description = "(new item)";
- /** Menu option level */
- var $menu_level = 0;
- /** Width of option in pixels */
- var $width = 100;
- /** Height of option in pixels */
- var $height = 18;
- // Private
- /** Whether menuoption exists in database
- @access private */
- var $exists = false;
- /** menuoption ID
- @access private */
- var $menuoptionid;
- /** menu ID the option belongs to
- @access private */
- var $menu_id;
- /** Parent ID of this menu option
- @access private */
- var $parent_id = 0;
- /** Array of user groups allowed to access this menuoption
- @access private */
- var $user_groups = array();
- /** User type restriction
- @access private */
- var $user_type = "";
- /** Order of display
- @access private */
- var $display_order = 0;
- /** Internal field which combines the sitepage
- and the sitepage_parms into an action.
- @access private */
- var $action = "";
- /** Target site webpage when clicked
- @access private */
- var $sitepage = MENU_ITEM_SUBMENU;
- /** Paramter string to pass on webpage URL
- @access private */
- var $sitepage_parms = "";
- /** Whether to apply auth code
- @access private */
- var $auth_code = false;
- /** Whether menuoption is active (displayed)
- @access private */
- var $active = true;
- /** When menu option was last modified (datetime)
- @access private */
- var $last_modified;
- /** True if this menu option is the parent of sub-menu options
- @access private */
- var $is_parent = false;
- // ....................................................................
- /**
- * Constructor
- * Create a new menuoption object.
- * @param string $id The unique identity of the menuoption.
- */
- function menuoption($id=NEW_MENUOPTION) {
- $this->menuoptionid = $id;
- $this->get($id);
- } // menuoption
- // ....................................................................
- /**
- * Get the menuoption.
- * Retrieves the specified menuoption from database.
- * @param string $id The unique integer identity of the menuoption to get.
- */
- function get($id) {
- debug_trace($this);
- $this->exists = false;
- if ($id != NEW_MENUOPTION) {
- // Try and read in existing menuoption info..
- $q = "SELECT * FROM ax_menuoption";
- $q .= " WHERE menuoption_id=$id";
- $mnoQ = dbrecordset($q);
- if ($mnoQ->hasdata) {
- $this->menu_id = $mnoQ->field("menu_id");
- $this->parent_id = $mnoQ->field("parent_id");
- $this->user_groups = explode(",", $mnoQ->field("user_groups"));
- $this->user_type = $mnoQ->field("user_type");
- $this->menu_level = $mnoQ->field("menu_level");
- $this->label = $mnoQ->field("label");
- $this->description = $mnoQ->field("description");
- $this->display_order = $mnoQ->field("display_order");
- $this->action = $mnoQ->field("action");
- $this->sitepage = $mnoQ->field("sitepage");
- $this->sitepage_parms = $mnoQ->field("sitepage_parms");
- $this->auth_code = $mnoQ->istrue("auth_code");
- $this->active = $mnoQ->istrue("active");
- $this->last_modified = $mnoQ->field("last_modified");
- $this->width = $mnoQ->field("width");
- $this->height = $mnoQ->field("height");
- $this->is_parent = $mnoQ->istrue("is_parent");
- $this->exists = true;
- }
- }
- debug_trace();
- // Return true if at least the menuoption exists..
- return $this->exists;
- } // get
- // ....................................................................
- /**
- * Synchronise sitepage parameters with manually edited values. This
- * check ensures that if people have added stuff directly into the
- * ax_menuoption.action table field, we pick it up and sync it to our
- * sitepage_parms field. However this only occurs if there is nothing
- * defined in the sitepage_parms field.
- */
- function syncparms() {
- if ($this->action != "") {
- $actbits = explode("?", $this->action);
- $changed = false;
- if ($this->sitepage == "") {
- if (isset($actbits[0]) && $actbits[0] != "") {
- $this->sitepage = $actbits[0];
- $changed = true;
- }
- }
- if ($this->sitepage_parms == "") {
- if (isset($actbits[1]) && $actbits[1] != "") {
- $this->sitepage_parms = $actbits[1];
- $changed = true;
- }
- }
- if ($changed) $this->put();
- }
- } // syncparms
- // ....................................................................
- /**
- * Save the menuoption.
- * Save this menuoption to the database. Create a new one if it
- * doesn't already exist.
- */
- function put() {
- debug_trace($this);
- // Deal with brand new menuoption..
- if (!$this->exists) {
- // If we are in need of a new ID, then get one..
- if ($this->menuoptionid == NEW_MENUOPTION) {
- $this->menuoptionid =
- get_next_sequencevalue(
- "seq_menuoption_id",
- "ax_menuoption",
- "menuoption_id"
- );
- }
- $mnoQ = new dbinsert("ax_menuoption");
- $mnoQ->set("menuoption_id", $this->menuoptionid);
- }
- else {
- $mnoQ = new dbupdate("ax_menuoption");
- $mnoQ->where("menuoption_id=$this->menuoptionid");
- }
- $mnoQ->set("menu_id", $this->menu_id);
- $mnoQ->set("parent_id", defaulted($this->parent_id, 0));
- $mnoQ->set("user_groups", implode(",", $this->user_groups));
- $mnoQ->set("user_type", $this->user_type);
- $mnoQ->set("menu_level", defaulted($this->menu_level, MENU_LEVEL0));
- $mnoQ->set("label", $this->label);
- $mnoQ->set("description", $this->description);
- $mnoQ->set("display_order", defaulted($this->display_order, 0));
- $mnoQ->set("sitepage", $this->sitepage);
- $mnoQ->set("sitepage_parms", $this->sitepage_parms);
- $mnoQ->set("auth_code", $this->auth_code);
- $mnoQ->set("active", $this->active);
- $mnoQ->set("width", defaulted($this->width, 100));
- $mnoQ->set("height", defaulted($this->height, 18));
- $mnoQ->set("is_parent", $this->is_parent);
- if ($this->sitepage_parms != "") {
- $mnoQ->set("action", $this->sitepage . "?" . $this->sitepage_parms);
- }
- else {
- $mnoQ->set("action", $this->sitepage);
- }
- $mnoQ->set("last_modified", 'now()');
- $this->exists = $mnoQ->execute();
- debug_trace();
- } // put
- // ....................................................................
- /**
- * Delete the menuoption.
- * Delete this menuoption from the database.
- */
- function delete() {
- debug_trace($this);
- dbcommand("DELETE FROM ax_menuoption WHERE menuoption_id=$this->menuoptionid");
- debug_trace();
- } // delete
- } // menuoption class
- // ----------------------------------------------------------------------
- /**
- * The Menu Option Instance
- * This class encapsulates an instance of a menuoption, including all the
- * various properties (parent, menu_level, description etc. that a menu option
- * might have.
- * @package menu
- * @access private
- */
- class menuop_instance {
- var $id = "";
- var $menu_level = 0;
- var $label = "";
- var $desc = "";
- var $action = "";
- var $target = "";
- var $authcode = false;
- var $parent = "";
- var $children = "";
- var $expanded = false;
- var $menu_heading = false;
- // ....................................................................
- /**
- * Create a new menu option.
- * @param integer $id The unique menu option ID
- * @param integer $menu_level The level this menu option is at (0 = top)
- * @param string $label The menu option label
- * @param string $desc The menu option long description
- * @param string $act The menu option action (eg. path to webpage)
- * @param string $targ The menu option target frame (eg. '_new')
- * @param boolean $auth Whether to apply auth_code or not true or false
- * @param integer $parent The menu option ID of the parent of this menu option
- * @param boolean $is_parent Whether this option is parent of other options
- */
- function menuop_instance($id, $menu_level, $label="", $desc="", $act="", $targ="", $authcode=false, $parent="", $is_parent=false) {
- $this->id = $id;
- $this->menu_level = $menu_level;
- $this->label = $label;
- $this->desc = $desc;
- $this->action = $act;
- $this->target = $targ;
- $this->authcode = $authcode;
- $this->parent = $parent;
- $this->is_parent = $is_parent;
- } // menuop_instance
- // ....................................................................
- /**
- * Return menu option details string.
- * Return the menu option details as a "|" delimited string
- * @return string The details packed into a "|" delimited string
- */
- function details() {
- return "$this->menu_level"
- . "|$this->label"
- . "|$this->desc"
- . "|$this->action"
- . "|$this->target"
- . "|" . ($this->authcode ? "t" : "f")
- ;
- } // details
- // ....................................................................
- /** Return true if this menu option is a sub-menu heading option, ie.
- * not an option which targets a webpage, but one which is a heading
- * for further sub-menu options.
- * @return boolean True if this menu option is a menu heading.
- */
- function is_submenuheading() {
- return ($this->is_parent);
- } // is_submenuheading
- // ....................................................................
- /** Return true if this menu option is a special-function pseudo menu
- * item such as a spacer or a line separator.
- * @return boolean True if this menu option is a special-function one
- */
- function is_pseudo() {
- return (
- $this->label == MENU_ITEM_SPACER
- || $this->label == MENU_ITEM_SEPARATOR
- );
- } // is_pseudo
- } // menuop_instance
- // ----------------------------------------------------------------------
- /**
- * A Menu Instance
- * This class encapsulates an instance of a menu, including its present
- * state in terms of expanded/collapsed headings, what is visible and
- * what is not, and the currently active (selected) menu-option.This class
- * is used by classes treemenu, and by hvmenu as a common container of menu
- * structure data, in a form most useful to them. This class is also apt
- * for serialization, in order to save menu structure state - eg. in the
- * ax_wwwsession.menu_state field.
- * @package menu
- * @access private
- */
- class menu_instance {
- /** The ID of the menu */
- var $menu_id = "";
- /** The name of the menu */
- var $menu_name = "";
- /** The language of the menu (0 = default) */
- var $language = 0;
- /** Array of menuop_instance objects */
- var $menu_ops = array();
- /** Current menu option (selected) */
- var $current_menu_option = "";
- /** Array of IDs of top-level menu options */
- var $menu_top = array();
- /** Timestamp last read from DB */
- var $last_readts = 0;
- /** Overall validity flag */
- var $valid = false;
- /** Max. no. of levels in this menu */
- var $level_depth = 0;
- /** Max width of menu items per level in pixels
- @access private */
- var $level_widths = array();
- /** Max height of menu items per level in pixels
- @access private */
- var $level_heights = array();
- // ....................................................................
- /** Create a menu instance.
- * This constructor gets the complete menu structure from the database
- * and populates menu options arrays etc.
- * @param string $menu_name The name of the menu to instantiate.
- * @param string $lang The optional language variant of this menu.
- */
- function menu_instance($menu_name, $lang=-1) {
- global $RESPONSE;
- $this->menu_name = $menu_name;
- // Set the language..
- if ($lang != -1) {
- $this->language = $lang;
- }
- elseif (isset($RESPONSE) && $RESPONSE->multilang && isset($RESPONSE->languages[0])) {
- $this->language = $RESPONSE->languages[0];
- }
- $this->get();
- } // menu_instance
- // ....................................................................
- /** Return count of total menuoptions in this menu */
- function menuop_count() {
- return count($this->menu_ops);
- } // menuop_count
- // ....................................................................
- /**
- * Create a new menu option instance and stash it in our menu under
- * the given id.
- * @param integer $id The unique menu option ID
- * @param integer $menu_level The level this menu option is at (0 = top)
- * @param string $label The menu option label
- * @param string $desc The menu option long description
- * @param string $act The menu option action (eg. path to webpage)
- * @param string $authcode Whether to apply auth_code or not true or false
- * @param integer $parent The menu option ID of the parent of this menu option
- * @param boolean $is_parent Whether this option is parent of other options
- */
- function add_menuop($id, $menu_level, $label="", $desc="", $act="", $targ="", $authcode=false, $parent="", $is_parent=false) {
- $this->menu_ops[$id] =
- new menuop_instance($id, $menu_level, $label, $desc, $act, $targ, $authcode, $parent, $is_parent);
- } // add_menuop
- // ....................................................................
- /** Return true if menu option exists.
- * @param integer $id The unique menu option ID
- * @return boolean True if the menu option of given ID exists
- */
- function menuop_exists($id) {
- return isset($this->menu_ops[$id]);
- } // menuop_exists
- // ....................................................................
- /** Return the menu option object.
- * Returns the menuoption object of the given ID, or false if it
- * doesn't exist.
- * @param integer $id The unique menu option ID
- * @return object The menu option object of the given ID, or false
- */
- function menuop($id) {
- if (isset($this->menu_ops[$id])) {
- return $this->menu_ops[$id];
- }
- else {
- return false;
- }
- } // menuop
- // ....................................................................
- /** Return menu option details string.
- * The details string returned contains the menu level, label, desc,
- * action and authcode flag in a string all delimited by "|".
- * @param integer $id The unique menu option ID
- * @return string The details packed into a "|" delimited string
- */
- function menuop_details($id) {
- $s = "";
- if ($this->menuop_exists($id)) {
- $mop = $this->menu_ops[$id];
- $s = $mop->details();
- }
- return $s;
- } // menuop_details
- // ....................................................................
- /**
- * Get menu data if modified.
- * Gets all the menu data from database if modified since last time we
- * read it.
- * @return boolean True if the menu was modified, and hence got.
- */
- function get_if_modified() {
- global $RESPONSE;
- if ($RESPONSE->cachecontrol == "refresh") {
- $modified = true;
- }
- else {
- $modified = false;
- $last_read = timestamp_to_datetime($this->last_readts);
- $q = "SELECT COUNT(*) AS tot FROM ax_menuoption";
- $q .= " WHERE menu_id=$this->menu_id";
- $q .= " AND last_modified > '$last_read'";
- $modQ = dbrecordset($q);
- if ($modQ->field("tot") > 0) {
- $modified = true;
- }
- if (!$modified) {
- $q = "SELECT COUNT(*) AS tot FROM ax_menu";
- $q .= " WHERE menu_id=$this->menu_id";
- $q .= " AND last_modified > '$last_read'";
- $modQ = dbrecordset($q);
- if ($modQ->field("tot") > 0) {
- $modified = true;
- }
- }
- }
- if ($modified) {
- $this->get();
- }
- return $modified;
- } // get_if_modified
- // ....................................................................
- /**
- * Get menu last modified timestamp.
- * @return integer Unix timestamp when menu was last modified.
- */
- function get_lastmodified_ts() {
- $lastmodified = 0;
- $q = "SELECT MAX(last_modified) FROM ax_menuoption";
- $q .= " WHERE menu_id=$this->menu_id";
- $modQ = dbrecordset($q);
- $ts1 = datetime_to_timestamp($modQ->field("last_modified"));
- $q = "SELECT last_modified FROM ax_menu";
- $q .= " WHERE menu_id=$this->menu_id";
- $modQ = dbrecordset($q);
- $ts2 = datetime_to_timestamp($modQ->field("last_modified"));
- if ($ts2 > $ts1) $lastmodified = $ts2;
- else $lastmodified = $ts1;
- return $lastmodified;
- } // get_lastmodified_ts
- // ....................................................................
- /**
- * Get menu data.
- * Populates the complete menu data instance vars from the database.
- */
- function get() {
- global $RESPONSE;
- // MENU ITEM DETAIL..
- $this->valid = false;
- $this->menu_ops = array();
- $this->menu_top = array();
- $mno_children = array();
- // Get menu, fall back to default if not found..
- $tryagain = true;
- do {
- $tryagain = ($this->language != 0);
- $q = "SELECT *";
- $q .= " FROM ax_menu m, ax_menuoption mo";
- $q .= " WHERE m.menu_name='" . escape_string($this->menu_name) . "'";
- $q .= " AND m.lang_id=$this->language";
- $q .= " AND mo.menu_id=m.menu_id";
- $q .= " AND m.active=TRUE";
- $q .= " AND mo.active=TRUE";
- $q .= " ORDER BY mo.menu_level,mo.parent_id,mo.display_order";
- $item = dbrecordset($q);
- if ($item->hasdata) {
- $tryagain = false;
- }
- else {
- debugbr("menu language not found ($this->language): falling back to default", DBG_DEBUG);
- $this->language = 0;
- }
- } while ($tryagain);
- if ($item->hasdata) {
- $this->valid = true;
- $this->menu_id = $item->field("menu_id");
- $topcount = 0;
- do {
- $mopid = $item->field("menuoption_id");
- $mnu_ugroups = $item->field("user_groups");
- $mnu_usertype = $item->field("user_type");
- if ($mnu_ugroups == ""
- || (!isset($RESPONSE) || $RESPONSE->ismemberof_group_in($mnu_ugroups))) {
- if ($mnu_usertype == ""
- || (!isset($RESPONSE) || ($RESPONSE->user_type == $mnu_usertype))) {
- $parent_id = $item->field("parent_id");
- $menu_level = $item->field("menu_level");
- $label = $item->field("label");
- $desc = $item->field("description");
- $action = $item->field("action");
- $target = $item->field("target");
- $authcode = $item->istrue("auth_code");
- $is_parent = $item->istrue("is_parent");
- if ($menu_level == 0) {
- $topcount += 1;
- $this->menu_top[$topcount] = $mopid;
- }
- if ($parent_id != "" && $parent_id != 0) {
- if (isset($mno_children[$parent_id])) {
- $mno_children[$parent_id] .= "|";
- }
- $mno_children[$parent_id] .= $mopid;
- }
- // Store menuoption..
- $this->add_menuop(
- $mopid,
- $menu_level,
- $label,
- $desc,
- $action,
- $target,
- $authcode,
- $parent_id,
- $is_parent
- );
- // Level depth recording..
- if ($menu_level > $this->level_depth) {
- $this->level_depth = $menu_level;
- }
- } // user type check
- } // memberof
- } while ($item->get_next());
- // Assign children lists
- foreach ($mno_children as $mopid => $childlist) {
- $menuitem = $this->menu_ops[$mopid];
- $menuitem->children = $childlist;
- $this->menu_ops[$mopid] = $menuitem;
- }
- // Register last time we read it..
- $this->last_readts = time() + 10;
- // Get max widths and heights for each level..
- $this->level_widths = array();
- $this->level_heights = array();
- for ($level = 0; $level <= $this->level_depth; $level++) {
- $q = "SELECT MAX(width) AS maxw, MAX(height) AS maxh";
- $q .= " FROM ax_menuoption";
- $q .= " WHERE menu_id=$this->menu_id";
- $q .= " AND menu_level=$level";
- $moQ = dbrecordset($q);
- if ($moQ->hasdata) {
- $this->level_widths[$level] = $moQ->field("maxw");
- $this->level_heights[$level] = $moQ->field("maxh");
- }
- } // for
- } // hasdata
- } // get
- } // menu_instance class
- ?>
Documentation generated by phpDocumentor 1.3.0RC3